diff --git a/proxy/.eslintrc.cjs b/.eslintrc.cjs similarity index 100% rename from proxy/.eslintrc.cjs rename to .eslintrc.cjs diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 177dd8e5e..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,69 +0,0 @@ -module.exports = { - "env": { - "browser": false, - "es6": true - }, - "extends": "standard", - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module" - }, - "rules": { - "indent": [ "error", 4 ], - "linebreak-style": [ "error", "unix" ], - "quotes": [ "error", "double" ], - "semi": [ "error", "always" ], - "camelcase": "off", - // "no-unused-vars": "off", - "eqeqeq": "off", - "comma-dangle": [ "error", "never" ], - "comma-style": [ "error", "last" ], - "comma-spacing": "off", - "space-before-function-paren": [ "error", "never" ], - "space-in-parens": [ "error", "always" ], - "keyword-spacing": [ "error", { - "overrides": { - "if": { "before": false, "after": false }, - "else": { "before": true, "after": true }, - "for": { "before": false, "after": false }, - "while": { "before": false, "after": false } - } - } ], - "space-before-blocks": [ "error", "always" ], - "array-bracket-spacing": [ "error", "always" ], - "object-curly-spacing": [ "error", "always" ], - "space-unary-ops": "off", - "spaced-comment": "off", - "curly": [ "error", "multi-or-nest" ], - "nonblock-statement-body-position": [ "error", "below" ], - "one-var": "off", - "no-unneeded-ternary": "off", - "no-cond-assign": [ "error", "always" ], - "no-console": "off", - "new-cap": "off", - "no-tabs": "off", - "no-mixed-spaces-and-tabs": "off", - "no-prototype-builtins": "off", - "quote-props": "off", - "no-undef": "off", - "no-useless-return": "off", - "no-new": "off", - "no-useless-constructor": "off", - "no-lone-blocks": "off", - "no-fallthrough": "off", - "no-useless-catch": "off", - "padded-blocks": "off", - "no-use-before-define": "off", // [ "error", { "variables": false, "functions": false } ], - "lines-between-class-members": [ "error", "never" ], - "no-var": "error", - "no-unused-vars": "error", - "object-shorthand": 0, - "multiline-ternary": "off", - "max-len": [ "error", { "code": 100, "tabWidth": 4 } ], - "max-lines-per-function": [ "error", { "max": 200, "skipBlankLines": false } ] - } -}; diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 000000000..8bb66f6a2 --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,10 @@ +#!/bin/bash + +set -e + +if [[ $(npx cspell -- --no-summary $1 2> /dev/null) ]] +then + echo "It looks like you have spell-checking errors in your commit message." + npx cspell -- --no-summary $1 + exit 1 +fi diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 000000000..d091c348c --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,17 @@ +#!/bin/bash + +# cSpell:words gpgsign + +set -e + +GPG_SIGN_ENABLED=$(git config commit.gpgsign || true) +if ! [[ "$GPG_SIGN_ENABLED" == "true" ]] +then + echo "Enable GPG signature for new commits"; + exit 1; +fi + +files=$(git diff --cached --name-only) +npx cspell -- --no-summary $files + +yarn fullCheck diff --git a/proxy/.openzeppelin/mainnet.json b/.openzeppelin/mainnet.json similarity index 100% rename from proxy/.openzeppelin/mainnet.json rename to .openzeppelin/mainnet.json diff --git a/proxy/.solcover.js b/.solcover.js similarity index 100% rename from proxy/.solcover.js rename to .solcover.js diff --git a/proxy/.solhint.json b/.solhint.json similarity index 100% rename from proxy/.solhint.json rename to .solhint.json diff --git a/proxy/.solhintignore b/.solhintignore similarity index 100% rename from proxy/.solhintignore rename to .solhintignore diff --git a/proxy/DEPLOYED b/DEPLOYED similarity index 100% rename from proxy/DEPLOYED rename to DEPLOYED diff --git a/README.md b/README.md index 1fd45b15a..245bb9380 100644 --- a/README.md +++ b/README.md @@ -15,24 +15,139 @@ Please see [SECURITY.md](.github/SECURITY.md) for audit reports and reporting po IMA consists of the following three parts: -1) `Mainnet` smart contracts. -2) `SKALE Chain` smart contracts. -3) A containerized [IMA Agent](https://github.com/skalenetwork/ima-agent) application. +1) `Mainnet` smart contracts. +2) `SKALE Chain` smart contracts. +3) A containerized [IMA Agent](https://github.com/skalenetwork/ima-agent) application. Smart contracts are interfaces for any software working with `Mainnet` and `SKALE Chain` like other smart contracts deployed there or software connecting these Ethereum networks. The Agent is a Node JS application connecting the smart contracts on Mainnet with SKALE Chains. -## Components Structure +## SKALE IMA Proxy -### Proxy +SKALE Interchain Messaging Smart Contracts -IMA proxy is the Solidity part of IMA containing `Mainnet` and `SKALE Chain` smart contracts. +Proxy is a library with smart contracts for the SKALE Interchain Messaging Agent. This system allows transferring ETH, ERC20 and ERC721 and is based on the Message Proxy system. + +Smart contract language - Solidity 0.5.10 +NodeJS version - 10.16.0 +NPM version - 6.9.0 + +### Message Proxy system + +This system allows sending and receiving messages from other chains. `MessageProxy.sol` contract needs to be deployed to Mainnet, and deployed to each SKALE chain to use it with the SKALE Interchain Messaging Agent. +You can use MessageProxy contract separately by Interchain Messaging Smart Contracts: + +1) Add interface: + + ```solidity + interface Proxy { + function postOutgoingMessage( + string calldata targetSchainName, + address targetContract, + uint256 amount, + address to, + bytes calldata data + ) + external; + } + ``` + +2) Write `postMessage` function, which will receive and process messages from other chains: + + ```solidity + function postMessage( + address sender, + string memory fromSchainName, + address payable to, + uint256 amount, + bytes memory data + ) + public + { + ... + } + ``` + +3) Add the address of MessageProxy on some chain: + Data of Smart contracts stores in `data` folder + +4) Then continue developing your dApp + +### Ether clone on SKALE chain + +There is a Wrapped Ether clone(EthERC20.sol) on SKALE chains - it is an ERC20 token and inherits the known ERC-20 approve issue. Please find more details here + +### Interchain Messaging Agent system + +This system sends and receives ETH, ERC20, and ERC721 tokens from other chains. +It consists of 3 additional smart contracts (not including MessageProxy contract): + +1) `DepositBox.sol` - contract only on a mainnet: DepositBox can transfer ETH and ERC20, ERC721 tokens to other chains. \- `deposit(string memory schainName, address to)` - transfer ETH. ... +2) `TokenManager.sol` +3) `TokenFactory.sol` + +### Install + +1) Clone this repo +2) run `npm install` +3) run `npm start`, this command will compile contracts + +### Deployment + +Configure your networks for SKALE chain and mainnet in `truffle-config.js` + +There are several example networks in comments. + +The `.env` file should include the following variables: + +```bash +URL_W3_ETHEREUM="your mainnet RPC url, it also can be an infura endpoint" +URL_W3_S_CHAIN="your SKALE chain RPC url, it also can be an infura endpoint" +CHAIN_NAME_SCHAIN="your SKALE chain name" +PRIVATE_KEY_FOR_ETHEREUM="your private key for mainnet" +PRIVATE_KEY_FOR_SCHAIN="your private key for SKALE chain" +ACCOUNT_FOR_ETHEREUM="your account for mainnet" +ACCOUNT_FOR_SCHAIN="your account for SKALE chain" +NETWORK_FOR_ETHEREUM="your created network for mainnet" +NETWORK_FOR_SCHAIN="your created network for SKALE chain" +``` + +- deploy only to your mainnet: + +```bash +npm run deploy-to-mainnet +``` + +- deploy only to your schain: + +```bash +npm run deploy-to-schain +``` + +- deploy only to your mainnet and to schain: + +```bash +npm run deploy-to-both +``` + +#### Generate IMA data file for skale-node + +Results will be saved to `[RESULTS_FOLDER]/ima_data.json` + +- `ARTIFACTS_FOLDER` - path to `build/contracts` folder +- `RESULTS_FOLDER` - path to the folder where `ima_data.json` will be saved + +```bash +cd proxy +npm run compile +python ima_datafile_generator.py [ARTIFACTS_FOLDER] [RESULTS_FOLDER] +``` ## For more information -- [SKALE Network Website](https://skale.network) -- [SKALE Network Twitter](https://twitter.com/SkaleNetwork) -- [SKALE Network Blog](https://skale.network/blog) +- [SKALE Network Website](https://skale.network) +- [SKALE Network Twitter](https://twitter.com/SkaleNetwork) +- [SKALE Network Blog](https://skale.network/blog) Learn more about the SKALE community over on [Discord](https://discord.gg/vvUtWJB). diff --git a/proxy/contracts/MessageProxy.sol b/contracts/MessageProxy.sol similarity index 100% rename from proxy/contracts/MessageProxy.sol rename to contracts/MessageProxy.sol diff --git a/proxy/contracts/Messages.sol b/contracts/Messages.sol similarity index 100% rename from proxy/contracts/Messages.sol rename to contracts/Messages.sol diff --git a/proxy/contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol b/contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol similarity index 100% rename from proxy/contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol rename to contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol diff --git a/proxy/contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol b/contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol similarity index 100% rename from proxy/contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol rename to contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol diff --git a/proxy/contracts/extensions/interfaces/MessageProxyClient.sol b/contracts/extensions/interfaces/MessageProxyClient.sol similarity index 100% rename from proxy/contracts/extensions/interfaces/MessageProxyClient.sol rename to contracts/extensions/interfaces/MessageProxyClient.sol diff --git a/proxy/contracts/extensions/interfaces/MessageReceiver.sol b/contracts/extensions/interfaces/MessageReceiver.sol similarity index 100% rename from proxy/contracts/extensions/interfaces/MessageReceiver.sol rename to contracts/extensions/interfaces/MessageReceiver.sol diff --git a/proxy/contracts/extensions/interfaces/MessageSender.sol b/contracts/extensions/interfaces/MessageSender.sol similarity index 100% rename from proxy/contracts/extensions/interfaces/MessageSender.sol rename to contracts/extensions/interfaces/MessageSender.sol diff --git a/proxy/contracts/mainnet/CommunityPool.sol b/contracts/mainnet/CommunityPool.sol similarity index 100% rename from proxy/contracts/mainnet/CommunityPool.sol rename to contracts/mainnet/CommunityPool.sol diff --git a/proxy/contracts/mainnet/DepositBox.sol b/contracts/mainnet/DepositBox.sol similarity index 100% rename from proxy/contracts/mainnet/DepositBox.sol rename to contracts/mainnet/DepositBox.sol diff --git a/proxy/contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol b/contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol similarity index 100% rename from proxy/contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol rename to contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol diff --git a/proxy/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol b/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol similarity index 100% rename from proxy/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol rename to contracts/mainnet/DepositBoxes/DepositBoxERC20.sol diff --git a/proxy/contracts/mainnet/DepositBoxes/DepositBoxERC721.sol b/contracts/mainnet/DepositBoxes/DepositBoxERC721.sol similarity index 100% rename from proxy/contracts/mainnet/DepositBoxes/DepositBoxERC721.sol rename to contracts/mainnet/DepositBoxes/DepositBoxERC721.sol diff --git a/proxy/contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol b/contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol similarity index 100% rename from proxy/contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol rename to contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol diff --git a/proxy/contracts/mainnet/DepositBoxes/DepositBoxEth.sol b/contracts/mainnet/DepositBoxes/DepositBoxEth.sol similarity index 100% rename from proxy/contracts/mainnet/DepositBoxes/DepositBoxEth.sol rename to contracts/mainnet/DepositBoxes/DepositBoxEth.sol diff --git a/proxy/contracts/mainnet/Linker.sol b/contracts/mainnet/Linker.sol similarity index 100% rename from proxy/contracts/mainnet/Linker.sol rename to contracts/mainnet/Linker.sol diff --git a/proxy/contracts/mainnet/MessageProxyForMainnet.sol b/contracts/mainnet/MessageProxyForMainnet.sol similarity index 100% rename from proxy/contracts/mainnet/MessageProxyForMainnet.sol rename to contracts/mainnet/MessageProxyForMainnet.sol diff --git a/proxy/contracts/mainnet/SkaleManagerClient.sol b/contracts/mainnet/SkaleManagerClient.sol similarity index 100% rename from proxy/contracts/mainnet/SkaleManagerClient.sol rename to contracts/mainnet/SkaleManagerClient.sol diff --git a/proxy/contracts/mainnet/Twin.sol b/contracts/mainnet/Twin.sol similarity index 100% rename from proxy/contracts/mainnet/Twin.sol rename to contracts/mainnet/Twin.sol diff --git a/proxy/contracts/schain/CommunityLocker.sol b/contracts/schain/CommunityLocker.sol similarity index 100% rename from proxy/contracts/schain/CommunityLocker.sol rename to contracts/schain/CommunityLocker.sol diff --git a/proxy/contracts/schain/DefaultAddresses.sol b/contracts/schain/DefaultAddresses.sol similarity index 100% rename from proxy/contracts/schain/DefaultAddresses.sol rename to contracts/schain/DefaultAddresses.sol diff --git a/proxy/contracts/schain/KeyStorage.sol b/contracts/schain/KeyStorage.sol similarity index 100% rename from proxy/contracts/schain/KeyStorage.sol rename to contracts/schain/KeyStorage.sol diff --git a/proxy/contracts/schain/MessageProxyForSchain.sol b/contracts/schain/MessageProxyForSchain.sol similarity index 100% rename from proxy/contracts/schain/MessageProxyForSchain.sol rename to contracts/schain/MessageProxyForSchain.sol diff --git a/proxy/contracts/schain/TokenManager.sol b/contracts/schain/TokenManager.sol similarity index 100% rename from proxy/contracts/schain/TokenManager.sol rename to contracts/schain/TokenManager.sol diff --git a/proxy/contracts/schain/TokenManagerLinker.sol b/contracts/schain/TokenManagerLinker.sol similarity index 100% rename from proxy/contracts/schain/TokenManagerLinker.sol rename to contracts/schain/TokenManagerLinker.sol diff --git a/proxy/contracts/schain/TokenManagers/TokenManagerERC1155.sol b/contracts/schain/TokenManagers/TokenManagerERC1155.sol similarity index 100% rename from proxy/contracts/schain/TokenManagers/TokenManagerERC1155.sol rename to contracts/schain/TokenManagers/TokenManagerERC1155.sol diff --git a/proxy/contracts/schain/TokenManagers/TokenManagerERC20.sol b/contracts/schain/TokenManagers/TokenManagerERC20.sol similarity index 100% rename from proxy/contracts/schain/TokenManagers/TokenManagerERC20.sol rename to contracts/schain/TokenManagers/TokenManagerERC20.sol diff --git a/proxy/contracts/schain/TokenManagers/TokenManagerERC721.sol b/contracts/schain/TokenManagers/TokenManagerERC721.sol similarity index 100% rename from proxy/contracts/schain/TokenManagers/TokenManagerERC721.sol rename to contracts/schain/TokenManagers/TokenManagerERC721.sol diff --git a/proxy/contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol b/contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol similarity index 100% rename from proxy/contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol rename to contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol diff --git a/proxy/contracts/schain/TokenManagers/TokenManagerEth.sol b/contracts/schain/TokenManagers/TokenManagerEth.sol similarity index 100% rename from proxy/contracts/schain/TokenManagers/TokenManagerEth.sol rename to contracts/schain/TokenManagers/TokenManagerEth.sol diff --git a/proxy/contracts/schain/bls/FieldOperations.sol b/contracts/schain/bls/FieldOperations.sol similarity index 100% rename from proxy/contracts/schain/bls/FieldOperations.sol rename to contracts/schain/bls/FieldOperations.sol diff --git a/proxy/contracts/schain/bls/Precompiled.sol b/contracts/schain/bls/Precompiled.sol similarity index 100% rename from proxy/contracts/schain/bls/Precompiled.sol rename to contracts/schain/bls/Precompiled.sol diff --git a/proxy/contracts/schain/bls/SkaleVerifier.sol b/contracts/schain/bls/SkaleVerifier.sol similarity index 100% rename from proxy/contracts/schain/bls/SkaleVerifier.sol rename to contracts/schain/bls/SkaleVerifier.sol diff --git a/proxy/contracts/schain/tokens/ERC1155OnChain.sol b/contracts/schain/tokens/ERC1155OnChain.sol similarity index 100% rename from proxy/contracts/schain/tokens/ERC1155OnChain.sol rename to contracts/schain/tokens/ERC1155OnChain.sol diff --git a/proxy/contracts/schain/tokens/ERC20OnChain.sol b/contracts/schain/tokens/ERC20OnChain.sol similarity index 100% rename from proxy/contracts/schain/tokens/ERC20OnChain.sol rename to contracts/schain/tokens/ERC20OnChain.sol diff --git a/proxy/contracts/schain/tokens/ERC721OnChain.sol b/contracts/schain/tokens/ERC721OnChain.sol similarity index 100% rename from proxy/contracts/schain/tokens/ERC721OnChain.sol rename to contracts/schain/tokens/ERC721OnChain.sol diff --git a/proxy/contracts/schain/tokens/EthErc20.sol b/contracts/schain/tokens/EthErc20.sol similarity index 100% rename from proxy/contracts/schain/tokens/EthErc20.sol rename to contracts/schain/tokens/EthErc20.sol diff --git a/proxy/contracts/test/ConfigReader.sol b/contracts/test/ConfigReader.sol similarity index 100% rename from proxy/contracts/test/ConfigReader.sol rename to contracts/test/ConfigReader.sol diff --git a/proxy/contracts/test/EtherbaseMock.sol b/contracts/test/EtherbaseMock.sol similarity index 100% rename from proxy/contracts/test/EtherbaseMock.sol rename to contracts/test/EtherbaseMock.sol diff --git a/proxy/contracts/test/FallbackEthTester.sol b/contracts/test/FallbackEthTester.sol similarity index 100% rename from proxy/contracts/test/FallbackEthTester.sol rename to contracts/test/FallbackEthTester.sol diff --git a/proxy/contracts/test/KeyStorageMock.sol b/contracts/test/KeyStorageMock.sol similarity index 100% rename from proxy/contracts/test/KeyStorageMock.sol rename to contracts/test/KeyStorageMock.sol diff --git a/proxy/contracts/test/Logger.sol b/contracts/test/Logger.sol similarity index 100% rename from proxy/contracts/test/Logger.sol rename to contracts/test/Logger.sol diff --git a/proxy/contracts/test/MessageProxyCaller.sol b/contracts/test/MessageProxyCaller.sol similarity index 100% rename from proxy/contracts/test/MessageProxyCaller.sol rename to contracts/test/MessageProxyCaller.sol diff --git a/proxy/contracts/test/MessageProxyForMainnetTester.sol b/contracts/test/MessageProxyForMainnetTester.sol similarity index 100% rename from proxy/contracts/test/MessageProxyForMainnetTester.sol rename to contracts/test/MessageProxyForMainnetTester.sol diff --git a/proxy/contracts/test/MessageProxyForSchainTester.sol b/contracts/test/MessageProxyForSchainTester.sol similarity index 100% rename from proxy/contracts/test/MessageProxyForSchainTester.sol rename to contracts/test/MessageProxyForSchainTester.sol diff --git a/proxy/contracts/test/MessageProxyForSchainWithoutSignature.sol b/contracts/test/MessageProxyForSchainWithoutSignature.sol similarity index 100% rename from proxy/contracts/test/MessageProxyForSchainWithoutSignature.sol rename to contracts/test/MessageProxyForSchainWithoutSignature.sol diff --git a/proxy/contracts/test/MessagesTester.sol b/contracts/test/MessagesTester.sol similarity index 100% rename from proxy/contracts/test/MessagesTester.sol rename to contracts/test/MessagesTester.sol diff --git a/proxy/contracts/test/PrecompiledMock.sol b/contracts/test/PrecompiledMock.sol similarity index 100% rename from proxy/contracts/test/PrecompiledMock.sol rename to contracts/test/PrecompiledMock.sol diff --git a/proxy/contracts/test/ReceiverGasLimitMainnetMock.sol b/contracts/test/ReceiverGasLimitMainnetMock.sol similarity index 100% rename from proxy/contracts/test/ReceiverGasLimitMainnetMock.sol rename to contracts/test/ReceiverGasLimitMainnetMock.sol diff --git a/proxy/contracts/test/ReceiverGasLimitSchainMock.sol b/contracts/test/ReceiverGasLimitSchainMock.sol similarity index 100% rename from proxy/contracts/test/ReceiverGasLimitSchainMock.sol rename to contracts/test/ReceiverGasLimitSchainMock.sol diff --git a/proxy/contracts/test/ReceiverMock.sol b/contracts/test/ReceiverMock.sol similarity index 100% rename from proxy/contracts/test/ReceiverMock.sol rename to contracts/test/ReceiverMock.sol diff --git a/proxy/contracts/test/SafeMock.sol b/contracts/test/SafeMock.sol similarity index 100% rename from proxy/contracts/test/SafeMock.sol rename to contracts/test/SafeMock.sol diff --git a/proxy/contracts/test/SkaleVerifierMock.sol b/contracts/test/SkaleVerifierMock.sol similarity index 100% rename from proxy/contracts/test/SkaleVerifierMock.sol rename to contracts/test/SkaleVerifierMock.sol diff --git a/proxy/contracts/test/TestCallReceiverContract.sol b/contracts/test/TestCallReceiverContract.sol similarity index 100% rename from proxy/contracts/test/TestCallReceiverContract.sol rename to contracts/test/TestCallReceiverContract.sol diff --git a/proxy/contracts/test/TestContractManager.sol b/contracts/test/TestContractManager.sol similarity index 100% rename from proxy/contracts/test/TestContractManager.sol rename to contracts/test/TestContractManager.sol diff --git a/proxy/contracts/test/TestNodes.sol b/contracts/test/TestNodes.sol similarity index 100% rename from proxy/contracts/test/TestNodes.sol rename to contracts/test/TestNodes.sol diff --git a/proxy/contracts/test/TestSchains.sol b/contracts/test/TestSchains.sol similarity index 100% rename from proxy/contracts/test/TestSchains.sol rename to contracts/test/TestSchains.sol diff --git a/proxy/contracts/test/TestSchainsInternal.sol b/contracts/test/TestSchainsInternal.sol similarity index 100% rename from proxy/contracts/test/TestSchainsInternal.sol rename to contracts/test/TestSchainsInternal.sol diff --git a/proxy/contracts/test/TestWallets.sol b/contracts/test/TestWallets.sol similarity index 100% rename from proxy/contracts/test/TestWallets.sol rename to contracts/test/TestWallets.sol diff --git a/proxy/contracts/test/erc20/ERC20IncorrectTransfer.sol b/contracts/test/erc20/ERC20IncorrectTransfer.sol similarity index 100% rename from proxy/contracts/test/erc20/ERC20IncorrectTransfer.sol rename to contracts/test/erc20/ERC20IncorrectTransfer.sol diff --git a/proxy/contracts/test/erc20/ERC20TransferWithFalseReturn.sol b/contracts/test/erc20/ERC20TransferWithFalseReturn.sol similarity index 100% rename from proxy/contracts/test/erc20/ERC20TransferWithFalseReturn.sol rename to contracts/test/erc20/ERC20TransferWithFalseReturn.sol diff --git a/proxy/contracts/test/erc20/ERC20TransferWithoutReturn.sol b/contracts/test/erc20/ERC20TransferWithoutReturn.sol similarity index 100% rename from proxy/contracts/test/erc20/ERC20TransferWithoutReturn.sol rename to contracts/test/erc20/ERC20TransferWithoutReturn.sol diff --git a/proxy/contracts/test/erc20/ERC20WithoutTransfer.sol b/contracts/test/erc20/ERC20WithoutTransfer.sol similarity index 100% rename from proxy/contracts/test/erc20/ERC20WithoutTransfer.sol rename to contracts/test/erc20/ERC20WithoutTransfer.sol diff --git a/proxy/contracts/test/erc20/RevertableERC20.sol b/contracts/test/erc20/RevertableERC20.sol similarity index 100% rename from proxy/contracts/test/erc20/RevertableERC20.sol rename to contracts/test/erc20/RevertableERC20.sol diff --git a/proxy/contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol b/contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol similarity index 100% rename from proxy/contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol rename to contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol diff --git a/proxy/data/.keep b/data/.keep similarity index 100% rename from proxy/data/.keep rename to data/.keep diff --git a/proxy/gas/calculateGas.ts b/gas/calculateGas.ts similarity index 100% rename from proxy/gas/calculateGas.ts rename to gas/calculateGas.ts diff --git a/proxy/hardhat.config.ts b/hardhat.config.ts similarity index 100% rename from proxy/hardhat.config.ts rename to hardhat.config.ts diff --git a/proxy/migrations/changeManifest.ts b/migrations/changeManifest.ts similarity index 100% rename from proxy/migrations/changeManifest.ts rename to migrations/changeManifest.ts diff --git a/proxy/migrations/deployMainnet.ts b/migrations/deployMainnet.ts similarity index 100% rename from proxy/migrations/deployMainnet.ts rename to migrations/deployMainnet.ts diff --git a/proxy/migrations/deploySchain.ts b/migrations/deploySchain.ts similarity index 100% rename from proxy/migrations/deploySchain.ts rename to migrations/deploySchain.ts diff --git a/proxy/migrations/deploySkaleManagerComponents.ts b/migrations/deploySkaleManagerComponents.ts similarity index 100% rename from proxy/migrations/deploySkaleManagerComponents.ts rename to migrations/deploySkaleManagerComponents.ts diff --git a/proxy/migrations/generateManifest.ts b/migrations/generateManifest.ts similarity index 100% rename from proxy/migrations/generateManifest.ts rename to migrations/generateManifest.ts diff --git a/proxy/migrations/hotfixUpgrade.ts b/migrations/hotfixUpgrade.ts similarity index 100% rename from proxy/migrations/hotfixUpgrade.ts rename to migrations/hotfixUpgrade.ts diff --git a/proxy/migrations/submitTransactions.ts b/migrations/submitTransactions.ts similarity index 100% rename from proxy/migrations/submitTransactions.ts rename to migrations/submitTransactions.ts diff --git a/proxy/migrations/transferOwnership.ts b/migrations/transferOwnership.ts similarity index 100% rename from proxy/migrations/transferOwnership.ts rename to migrations/transferOwnership.ts diff --git a/proxy/migrations/upgradeMainnet.ts b/migrations/upgradeMainnet.ts similarity index 100% rename from proxy/migrations/upgradeMainnet.ts rename to migrations/upgradeMainnet.ts diff --git a/proxy/migrations/upgradeSchain.ts b/migrations/upgradeSchain.ts similarity index 100% rename from proxy/migrations/upgradeSchain.ts rename to migrations/upgradeSchain.ts diff --git a/package.json b/package.json index 9c973e494..45dd74230 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,63 @@ { - "name": "skale-ima", + "name": "skale-ima-proxy", "private": true, "license": "AGPL-3.0", "author": "SKALE Labs and contributors", "scripts": { - "lint-check": "eslint ./test/*.*js", - "lint-fix": "eslint ./test/*.*js --fix", - "postinstall": "./postinstall.sh", - "check-outdated": "yarn outdated", - "upgrade-to-latest": "yarn upgrade --latest" + "compile": "npx hardhat compile", + "cleanCompile": "npx hardhat clean && yarn compile", + "deploy-to-both-chains": "yarn deploy-to-mainnet && yarn deploy-to-schain", + "deploy-to-mainnet": "VERSION=$(cat ../VERSION) npx hardhat run migrations/deployMainnet.ts --network mainnet", + "deploy-to-schain": "VERSION=$(cat ../VERSION) npx hardhat run migrations/deploySchain.ts --network schain", + "deploy-skale-manager-components": "npx hardhat run migrations/deploySkaleManagerComponents.ts --network mainnet", + "eslint": "npx eslint .", + "lint": "npx solhint \"contracts/**/*.sol\"", + "prepare": "yarn cleanCompile", + "test": "yarn tsc && npx hardhat test", + "tsc": "tsc --noEmit", + "slither": "slither .", + "fullcheck": "yarn lint && yarn tsc && yarn eslint && yarn slither", + "hooks": "git config core.hooksPath proxy/.githooks", + "no-hooks": "git config core.hooksPath .git/hooks" + }, + "dependencies": { + "@nomiclabs/hardhat-ethers": "^2.1.0", + "@openzeppelin/contracts-upgradeable": "^4.7.1", + "@openzeppelin/hardhat-upgrades": "^1.14.0", + "@skalenetwork/etherbase-interfaces": "^0.0.1-develop.20", + "@skalenetwork/ima-interfaces": "2.0.0", + "@skalenetwork/skale-manager-interfaces": "2.0.0", + "@skalenetwork/upgrade-tools": "^2.0.2", + "axios": "^0.21.4", + "dotenv": "^16.0.0", + "ethers": "^5.7.2", + "hardhat": "2.11.0 - 2.16.1" }, - "dependencies": {}, "devDependencies": { - "eslint": "^6.8.0", - "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.20.2", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.1" + "@nomiclabs/hardhat-etherscan": "^3.1.0", + "@nomiclabs/hardhat-waffle": "^2.0.2", + "@typechain/ethers-v5": "^11.1.1", + "@typechain/hardhat": "^7.0.0", + "@types/chai": "^4.2.12", + "@types/chai-almost": "^1.0.1", + "@types/chai-as-promised": "^7.1.3", + "@types/elliptic": "^6.4.14", + "@types/minimist": "^1.2.0", + "@types/mocha": "^9.1.0", + "@types/sinon-chai": "^3.2.5", + "@typescript-eslint/eslint-plugin": "^6.2.1", + "@typescript-eslint/parser": "^6.2.1", + "chai": "^4.2.0", + "chai-almost": "^1.0.1", + "chai-as-promised": "^7.1.1", + "eslint": "^8.46.0", + "ethereum-waffle": "^4.0.10", + "ganache": "7.9.2", + "solhint": "3.3.6", + "solidity-coverage": "^0.8.4", + "ts-generator": "^0.1.1", + "ts-node": "^8.10.2", + "typechain": "^8.3.1", + "typescript": "^5.1.6" } } diff --git a/proxy/predeployed/LICENSE b/predeployed/LICENSE similarity index 100% rename from proxy/predeployed/LICENSE rename to predeployed/LICENSE diff --git a/proxy/predeployed/MANIFEST.in b/predeployed/MANIFEST.in similarity index 100% rename from proxy/predeployed/MANIFEST.in rename to predeployed/MANIFEST.in diff --git a/proxy/predeployed/README.md b/predeployed/README.md similarity index 100% rename from proxy/predeployed/README.md rename to predeployed/README.md diff --git a/proxy/predeployed/src/ima_predeployed/__init__.py b/predeployed/build/lib/ima_predeployed/__init__.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/__init__.py rename to predeployed/build/lib/ima_predeployed/__init__.py diff --git a/predeployed/build/lib/ima_predeployed/addresses.py b/predeployed/build/lib/ima_predeployed/addresses.py new file mode 100644 index 000000000..dd22bf6c0 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/addresses.py @@ -0,0 +1,17 @@ +PROXY_ADMIN_ADDRESS = '0xd2aAa00000000000000000000000000000000000' +MESSAGE_PROXY_FOR_SCHAIN_ADDRESS = '0xd2AAa00100000000000000000000000000000000' +MESSAGE_PROXY_FOR_SCHAIN_IMPLEMENTATION_ADDRESS = '0xD2AAa001D2000000000000000000000000000000' +KEY_STORAGE_ADDRESS = '0xd2aaa00200000000000000000000000000000000' +KEY_STORAGE_IMPLEMENTATION_ADDRESS = '0xD2AAa002d2000000000000000000000000000000' +COMMUNITY_LOCKER_ADDRESS = '0xD2aaa00300000000000000000000000000000000' +COMMUNITY_LOCKER_IMPLEMENTATION_ADDRESS = '0xD2aaA003d2000000000000000000000000000000' +TOKEN_MANAGER_ETH_ADDRESS = '0xd2AaA00400000000000000000000000000000000' +TOKEN_MANAGER_ETH_IMPLEMENTATION_ADDRESS = '0xd2AaA004d2000000000000000000000000000000' +TOKEN_MANAGER_ERC20_ADDRESS = '0xD2aAA00500000000000000000000000000000000' +TOKEN_MANAGER_ERC20_IMPLEMENTATION_ADDRESS = '0xd2aAa005d2000000000000000000000000000000' +TOKEN_MANAGER_ERC721_ADDRESS = '0xD2aaa00600000000000000000000000000000000' +TOKEN_MANAGER_ERC721_IMPLEMENTATION_ADDRESS = '0xd2AAa006d2000000000000000000000000000000' +ETH_ERC20_ADDRESS = '0xD2Aaa00700000000000000000000000000000000' +ETH_ERC20_IMPLEMENTATION_ADDRESS = '0xD2aaA007d2000000000000000000000000000000' +TOKEN_MANAGER_LINKER_ADDRESS = '0xD2aAA00800000000000000000000000000000000' +TOKEN_MANAGER_LINKER_IMPLEMENTATION_ADDRESS = '0xd2aAA008D2000000000000000000000000000000' diff --git a/predeployed/build/lib/ima_predeployed/artifacts/AdminUpgradeabilityProxy.json b/predeployed/build/lib/ima_predeployed/artifacts/AdminUpgradeabilityProxy.json new file mode 100644 index 000000000..cda26649a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/AdminUpgradeabilityProxy.json @@ -0,0 +1,142 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "AdminUpgradeabilityProxy", + "sourceName": "contracts/proxy/AdminUpgradeabilityProxy.sol", + "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": "", + "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": "", + "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" + } + ], + "bytecode": "0x60806040526040516108d23803806108d28339818101604052606081101561002657600080fd5b8151602083015160408085018051915193959294830192918464010000000082111561005157600080fd5b90830190602082018581111561006657600080fd5b825164010000000081118282018810171561008057600080fd5b82525081516020918201929091019080838360005b838110156100ad578181015183820152602001610095565b50505050905090810190601f1680156100da5780820380516001836020036101000a031916815260200191505b50604052508491508290506100ee826101bf565b8051156101a6576000826001600160a01b0316826040518082805190602001908083835b602083106101315780518252601f199092019160209182019101610112565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610191576040519150601f19603f3d011682016040523d82523d6000602084013e610196565b606091505b50509050806101a457600080fd5b505b506101ae9050565b6101b782610231565b50505061025b565b6101d28161025560201b6103b41760201c565b61020d5760405162461bcd60e51b815260040180806020018281038252603b815260200180610897603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b3b151590565b61062d8061026a6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100985780635c60da1b146101185780638f28397014610149578063f851a4401461017c5761005d565b3661005d5761005b610191565b005b61005b610191565b34801561007157600080fd5b5061005b6004803603602081101561008857600080fd5b50356001600160a01b03166101ab565b61005b600480360360408110156100ae57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100d957600080fd5b8201836020820111156100eb57600080fd5b8035906020019184600183028401116401000000008311171561010d57600080fd5b5090925090506101e5565b34801561012457600080fd5b5061012d610292565b604080516001600160a01b039092168252519081900360200190f35b34801561015557600080fd5b5061005b6004803603602081101561016c57600080fd5b50356001600160a01b03166102cf565b34801561018857600080fd5b5061012d610389565b6101996103ba565b6101a96101a461041a565b61043f565b565b6101b3610463565b6001600160a01b0316336001600160a01b031614156101da576101d581610488565b6101e2565b6101e2610191565b50565b6101ed610463565b6001600160a01b0316336001600160a01b031614156102855761020f83610488565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d806000811461026c576040519150601f19603f3d011682016040523d82523d6000602084013e610271565b606091505b505090508061027f57600080fd5b5061028d565b61028d610191565b505050565b600061029c610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd61041a565b90506102cc565b6102cc610191565b90565b6102d7610463565b6001600160a01b0316336001600160a01b031614156101da576001600160a01b0381166103355760405162461bcd60e51b81526004018080602001828103825260368152602001806105876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61035e610463565b604080516001600160a01b03928316815291841660208301528051918290030190a16101d5816104c8565b6000610393610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd610463565b3b151590565b6103c2610463565b6001600160a01b0316336001600160a01b031614156104125760405162461bcd60e51b81526004018080602001828103825260328152602001806105556032913960400191505060405180910390fd5b6101a96101a9565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610491816104ec565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b6104f5816103b4565b6105305760405162461bcd60e51b815260040180806020018281038252603b8152602001806105bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220249c822daf23a4c4105d411560ffa6c4b3a5d68c227c3a6354de449e0b177f2264736f6c634300060c003343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100985780635c60da1b146101185780638f28397014610149578063f851a4401461017c5761005d565b3661005d5761005b610191565b005b61005b610191565b34801561007157600080fd5b5061005b6004803603602081101561008857600080fd5b50356001600160a01b03166101ab565b61005b600480360360408110156100ae57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100d957600080fd5b8201836020820111156100eb57600080fd5b8035906020019184600183028401116401000000008311171561010d57600080fd5b5090925090506101e5565b34801561012457600080fd5b5061012d610292565b604080516001600160a01b039092168252519081900360200190f35b34801561015557600080fd5b5061005b6004803603602081101561016c57600080fd5b50356001600160a01b03166102cf565b34801561018857600080fd5b5061012d610389565b6101996103ba565b6101a96101a461041a565b61043f565b565b6101b3610463565b6001600160a01b0316336001600160a01b031614156101da576101d581610488565b6101e2565b6101e2610191565b50565b6101ed610463565b6001600160a01b0316336001600160a01b031614156102855761020f83610488565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d806000811461026c576040519150601f19603f3d011682016040523d82523d6000602084013e610271565b606091505b505090508061027f57600080fd5b5061028d565b61028d610191565b505050565b600061029c610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd61041a565b90506102cc565b6102cc610191565b90565b6102d7610463565b6001600160a01b0316336001600160a01b031614156101da576001600160a01b0381166103355760405162461bcd60e51b81526004018080602001828103825260368152602001806105876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61035e610463565b604080516001600160a01b03928316815291841660208301528051918290030190a16101d5816104c8565b6000610393610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd610463565b3b151590565b6103c2610463565b6001600160a01b0316336001600160a01b031614156104125760405162461bcd60e51b81526004018080602001828103825260328152602001806105556032913960400191505060405180910390fd5b6101a96101a9565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610491816104ec565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b6104f5816103b4565b6105305760405162461bcd60e51b815260040180806020018281038252603b8152602001806105bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220249c822daf23a4c4105d411560ffa6c4b3a5d68c227c3a6354de449e0b177f2264736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/CommunityLocker.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/CommunityLocker.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/CommunityLocker.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/CommunityLocker.json b/predeployed/build/lib/ima_predeployed/artifacts/CommunityLocker.json new file mode 100644 index 000000000..bde638388 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/CommunityLocker.json @@ -0,0 +1,432 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "CommunityLocker", + "sourceName": "contracts/schain/CommunityLocker.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "schainHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "UserUnfrozed", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "checkAllowedToSendMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "communityPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newTokenManagerLinker", + "type": "address" + }, + { + "internalType": "address", + "name": "newCommunityPool", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract MessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newTimeLimitPerMessage", + "type": "uint256" + } + ], + "name": "setTimeLimitPerMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "timeLimitPerMessage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract TokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50611494806100206000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c806350f44280116100ad57806391d148541161007157806391d1485414610222578063a217fddf14610235578063ca15c8731461023d578063d547741f14610250578063f34822b41461026357610121565b806350f44280146101ca5780635573b8b6146101df57806382fd8c96146101e7578063884cee5a146101ef5780639010d07c1461020f57610121565b80632dc151de116100f45780632dc151de146101815780632f2ff15d1461018957806336568abe1461019c5780633b690b6b146101af57806348ed32ef146101b757610121565b806314d140b014610126578063237c667a14610144578063248a9ca31461015957806328c5e18214610179575b600080fd5b61012e610276565b60405161013b9190610fb5565b60405180910390f35b610157610152366004610d1d565b610285565b005b61016c610167366004610d5c565b61039f565b60405161013b9190610fd4565b61016c6103b4565b61012e6103fd565b610157610197366004610d74565b61040c565b6101576101aa366004610d74565b610454565b61016c610496565b6101576101c5366004610d5c565b61049c565b6101d26104c8565b60405161013b9190610ff4565b61012e6104eb565b61016c6104fa565b6102026101fd366004610da3565b610500565b60405161013b9190610fc9565b61012e61021d366004610e27565b6106d3565b610202610230366004610d74565b6106f4565b61016c61070c565b61016c61024b366004610d5c565b610711565b61015761025e366004610d74565b610728565b610157610271366004610e63565b610762565b6067546001600160a01b031681565b6066546040516374a9e4c960e11b81526001600160a01b039091169063e953c992906102b5903390600401610fb5565b60206040518083038186803b1580156102cd57600080fd5b505afa1580156102e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103059190610d40565b506001600160a01b0381166000908152606a602052604090205460ff166103475760405162461bcd60e51b815260040161033e90611171565b60405180910390fd5b6069546001600160a01b0382166000908152606b6020526040902054429101106103835760405162461bcd60e51b815260040161033e906112c6565b6001600160a01b03166000908152606b60205260409020429055565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016103e49190610f99565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b60008281526033602052604090206002015461042a90610230610879565b6104465760405162461bcd60e51b815260040161033e90611069565b610450828261087d565b5050565b61045c610879565b6001600160a01b0316816001600160a01b03161461048c5760405162461bcd60e51b815260040161033e9061136d565b61045082826108e6565b60685481565b6104a76000336106f4565b6104c35760405162461bcd60e51b815260040161033e90611307565b606955565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b60695481565b6065546000906001600160a01b0316331461052d5760405162461bcd60e51b815260040161033e90611336565b6067546001600160a01b0385811691161461055a5760405162461bcd60e51b815260040161033e906111a8565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200161058a9190610f99565b6040516020818303038152906040528051906020012085146105be5760405162461bcd60e51b815260040161033e906110f9565b60006105ca848461094f565b9050600781600c8111156105da57fe5b146105f75760405162461bcd60e51b815260040161033e906111df565b6105ff610cca565b6106098585610990565b6040818101516020808401516001600160a01b03166000908152606a9091529190912054919250151560ff909116151514156106575760405162461bcd60e51b815260040161033e906110b8565b604081810151602080840180516001600160a01b03166000908152606a90925290839020805460ff191692151592909217909155606854905191517f9b5ddb8096e31e93e8cd35890fad3bf2e0f04807e5dfc83591847d5f08ffe1ce926106be9291610fdd565b60405180910390a15060019695505050505050565b60008281526033602052604081206106eb90836109d8565b90505b92915050565b60008281526033602052604081206106eb90836109e4565b600081565b60008181526033602052604081206106ee906109f9565b60008281526033602052604090206002015461074690610230610879565b61048c5760405162461bcd60e51b815260040161033e90611228565b600054610100900460ff168061077b575061077b610a04565b80610789575060005460ff16155b6107a55760405162461bcd60e51b815260040161033e90611278565b600054610100900460ff161580156107d0576000805460ff1961ff0019909116610100171660011790555b6107d8610a15565b6107e3600033610446565b606580546001600160a01b038087166001600160a01b0319928316179092556066805492861692909116919091179055604051610824908690602001610f99565b60408051808303601f19018152919052805160209091012060685561012c606955606780546001600160a01b0319166001600160a01b0384161790558015610872576000805461ff00191690555b5050505050565b3390565b60008281526033602052604090206108959082610aa8565b15610450576108a2610879565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206108fe9082610abd565b156104505761090b610879565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008061095e83850185610d5c565b9050602081066109845761097c610977848381886113e3565b61094f565b9150506106ee565b61097c83850185610e48565b610998610cca565b60076109a4848461094f565b600c8111156109af57fe5b146109cc5760405162461bcd60e51b815260040161033e9061113a565b6106eb82840184610f21565b60006106eb8383610ad2565b60006106eb836001600160a01b038416610b17565b60006106ee82610b2f565b6000610a0f30610b33565b15905090565b600054610100900460ff1680610a2e5750610a2e610a04565b80610a3c575060005460ff16155b610a585760405162461bcd60e51b815260040161033e90611278565b600054610100900460ff16158015610a83576000805460ff1961ff0019909116610100171660011790555b610a8b610b39565b610a93610b39565b8015610aa5576000805461ff00191690555b50565b60006106eb836001600160a01b038416610bba565b60006106eb836001600160a01b038416610c04565b81546000908210610af55760405162461bcd60e51b815260040161033e90611027565b826000018281548110610b0457fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b3b151590565b600054610100900460ff1680610b525750610b52610a04565b80610b60575060005460ff16155b610b7c5760405162461bcd60e51b815260040161033e90611278565b600054610100900460ff16158015610a93576000805460ff1961ff0019909116610100171660011790558015610aa5576000805461ff001916905550565b6000610bc68383610b17565b610bfc575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106ee565b5060006106ee565b60008181526001830160205260408120548015610cc05783546000198083019190810190600090879083908110610c3757fe5b9060005260206000200154905080876000018481548110610c5457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080610c8457fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506106ee565b60009150506106ee565b6040518060600160405280610cdd610cf1565b815260006020820181905260409091015290565b60408051602081019091526000815290565b80356106ee8161143b565b8035600d81106106ee57600080fd5b600060208284031215610d2e578081fd5b8135610d398161143b565b9392505050565b600060208284031215610d51578081fd5b8151610d3981611450565b600060208284031215610d6d578081fd5b5035919050565b60008060408385031215610d86578081fd5b823591506020830135610d988161143b565b809150509250929050565b60008060008060608587031215610db8578182fd5b843593506020850135610dca8161143b565b9250604085013567ffffffffffffffff80821115610de6578384fd5b818701915087601f830112610df9578384fd5b813581811115610e07578485fd5b886020828501011115610e18578485fd5b95989497505060200194505050565b60008060408385031215610e39578182fd5b50508035926020909101359150565b600060208284031215610e59578081fd5b6106eb8383610d0e565b60008060008060808587031215610e78578384fd5b843567ffffffffffffffff80821115610e8f578586fd5b818701915087601f830112610ea2578586fd5b813581811115610eb0578687fd5b60209150610ec6601f8201601f191683016113bc565b8181528983838601011115610ed9578788fd5b8183850184830137908101820196909652610ef688888301610d03565b94505050610f078660408701610d03565b9150610f168660608701610d03565b905092959194509250565b60008183036060811215610f33578182fd5b610f3d60606113bc565b6020821215610f4a578283fd5b610f5460206113bc565b9150610f608585610d0e565b8252908152602083013590610f748261143b565b81602082015260408401359150610f8a82611450565b60408101919091529392505050565b60008251610fab81846020870161140b565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b600060208252825180602084015261101381604085016020870161140b565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526021908201527f467265657a696e6720737461746573206d75737420626520646966666572656e6040820152601d60fa1b606082015260800190565b60208082526021908201527f536f7572636520636861696e206e616d65206d757374206265204d61696e6e656040820152601d60fa1b606082015260800190565b6020808252601f908201527f4d6573736167652074797065206973206e6f7420467265657a65205573657200604082015260600190565b6020808252601a908201527f526563697069656e74206d75737420626520756e66726f7a656e000000000000604082015260600190565b6020808252601c908201527f53656e646572206d75737420626520436f6d6d756e697479506f6f6c00000000604082015260600190565b60208082526029908201527f546865206d6573736167652073686f756c6420636f6e7461696e20612066726f6040820152687a656e20737461746560b81b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f547279696e6720746f2073656e64206d6573736167657320746f6f206f6674656040820152603760f91b606082015260800190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b6020808252601d908201527f53656e646572206973206e6f742061206d6573736167652070726f7879000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60405181810167ffffffffffffffff811182821017156113db57600080fd5b604052919050565b600080858511156113f2578182fd5b838611156113fe578182fd5b5050820193919092039150565b60005b8381101561142657818101518382015260200161140e565b83811115611435576000848401525b50505050565b6001600160a01b0381168114610aa557600080fd5b8015158114610aa557600080fdfea2646970667358221220a16be2dcea165d37c26d9bebb8c6ad17976baccf1a7ed1cbd6dc1de613a875bf64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101215760003560e01c806350f44280116100ad57806391d148541161007157806391d1485414610222578063a217fddf14610235578063ca15c8731461023d578063d547741f14610250578063f34822b41461026357610121565b806350f44280146101ca5780635573b8b6146101df57806382fd8c96146101e7578063884cee5a146101ef5780639010d07c1461020f57610121565b80632dc151de116100f45780632dc151de146101815780632f2ff15d1461018957806336568abe1461019c5780633b690b6b146101af57806348ed32ef146101b757610121565b806314d140b014610126578063237c667a14610144578063248a9ca31461015957806328c5e18214610179575b600080fd5b61012e610276565b60405161013b9190610fb5565b60405180910390f35b610157610152366004610d1d565b610285565b005b61016c610167366004610d5c565b61039f565b60405161013b9190610fd4565b61016c6103b4565b61012e6103fd565b610157610197366004610d74565b61040c565b6101576101aa366004610d74565b610454565b61016c610496565b6101576101c5366004610d5c565b61049c565b6101d26104c8565b60405161013b9190610ff4565b61012e6104eb565b61016c6104fa565b6102026101fd366004610da3565b610500565b60405161013b9190610fc9565b61012e61021d366004610e27565b6106d3565b610202610230366004610d74565b6106f4565b61016c61070c565b61016c61024b366004610d5c565b610711565b61015761025e366004610d74565b610728565b610157610271366004610e63565b610762565b6067546001600160a01b031681565b6066546040516374a9e4c960e11b81526001600160a01b039091169063e953c992906102b5903390600401610fb5565b60206040518083038186803b1580156102cd57600080fd5b505afa1580156102e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103059190610d40565b506001600160a01b0381166000908152606a602052604090205460ff166103475760405162461bcd60e51b815260040161033e90611171565b60405180910390fd5b6069546001600160a01b0382166000908152606b6020526040902054429101106103835760405162461bcd60e51b815260040161033e906112c6565b6001600160a01b03166000908152606b60205260409020429055565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016103e49190610f99565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b60008281526033602052604090206002015461042a90610230610879565b6104465760405162461bcd60e51b815260040161033e90611069565b610450828261087d565b5050565b61045c610879565b6001600160a01b0316816001600160a01b03161461048c5760405162461bcd60e51b815260040161033e9061136d565b61045082826108e6565b60685481565b6104a76000336106f4565b6104c35760405162461bcd60e51b815260040161033e90611307565b606955565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b60695481565b6065546000906001600160a01b0316331461052d5760405162461bcd60e51b815260040161033e90611336565b6067546001600160a01b0385811691161461055a5760405162461bcd60e51b815260040161033e906111a8565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200161058a9190610f99565b6040516020818303038152906040528051906020012085146105be5760405162461bcd60e51b815260040161033e906110f9565b60006105ca848461094f565b9050600781600c8111156105da57fe5b146105f75760405162461bcd60e51b815260040161033e906111df565b6105ff610cca565b6106098585610990565b6040818101516020808401516001600160a01b03166000908152606a9091529190912054919250151560ff909116151514156106575760405162461bcd60e51b815260040161033e906110b8565b604081810151602080840180516001600160a01b03166000908152606a90925290839020805460ff191692151592909217909155606854905191517f9b5ddb8096e31e93e8cd35890fad3bf2e0f04807e5dfc83591847d5f08ffe1ce926106be9291610fdd565b60405180910390a15060019695505050505050565b60008281526033602052604081206106eb90836109d8565b90505b92915050565b60008281526033602052604081206106eb90836109e4565b600081565b60008181526033602052604081206106ee906109f9565b60008281526033602052604090206002015461074690610230610879565b61048c5760405162461bcd60e51b815260040161033e90611228565b600054610100900460ff168061077b575061077b610a04565b80610789575060005460ff16155b6107a55760405162461bcd60e51b815260040161033e90611278565b600054610100900460ff161580156107d0576000805460ff1961ff0019909116610100171660011790555b6107d8610a15565b6107e3600033610446565b606580546001600160a01b038087166001600160a01b0319928316179092556066805492861692909116919091179055604051610824908690602001610f99565b60408051808303601f19018152919052805160209091012060685561012c606955606780546001600160a01b0319166001600160a01b0384161790558015610872576000805461ff00191690555b5050505050565b3390565b60008281526033602052604090206108959082610aa8565b15610450576108a2610879565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206108fe9082610abd565b156104505761090b610879565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008061095e83850185610d5c565b9050602081066109845761097c610977848381886113e3565b61094f565b9150506106ee565b61097c83850185610e48565b610998610cca565b60076109a4848461094f565b600c8111156109af57fe5b146109cc5760405162461bcd60e51b815260040161033e9061113a565b6106eb82840184610f21565b60006106eb8383610ad2565b60006106eb836001600160a01b038416610b17565b60006106ee82610b2f565b6000610a0f30610b33565b15905090565b600054610100900460ff1680610a2e5750610a2e610a04565b80610a3c575060005460ff16155b610a585760405162461bcd60e51b815260040161033e90611278565b600054610100900460ff16158015610a83576000805460ff1961ff0019909116610100171660011790555b610a8b610b39565b610a93610b39565b8015610aa5576000805461ff00191690555b50565b60006106eb836001600160a01b038416610bba565b60006106eb836001600160a01b038416610c04565b81546000908210610af55760405162461bcd60e51b815260040161033e90611027565b826000018281548110610b0457fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b3b151590565b600054610100900460ff1680610b525750610b52610a04565b80610b60575060005460ff16155b610b7c5760405162461bcd60e51b815260040161033e90611278565b600054610100900460ff16158015610a93576000805460ff1961ff0019909116610100171660011790558015610aa5576000805461ff001916905550565b6000610bc68383610b17565b610bfc575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106ee565b5060006106ee565b60008181526001830160205260408120548015610cc05783546000198083019190810190600090879083908110610c3757fe5b9060005260206000200154905080876000018481548110610c5457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080610c8457fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506106ee565b60009150506106ee565b6040518060600160405280610cdd610cf1565b815260006020820181905260409091015290565b60408051602081019091526000815290565b80356106ee8161143b565b8035600d81106106ee57600080fd5b600060208284031215610d2e578081fd5b8135610d398161143b565b9392505050565b600060208284031215610d51578081fd5b8151610d3981611450565b600060208284031215610d6d578081fd5b5035919050565b60008060408385031215610d86578081fd5b823591506020830135610d988161143b565b809150509250929050565b60008060008060608587031215610db8578182fd5b843593506020850135610dca8161143b565b9250604085013567ffffffffffffffff80821115610de6578384fd5b818701915087601f830112610df9578384fd5b813581811115610e07578485fd5b886020828501011115610e18578485fd5b95989497505060200194505050565b60008060408385031215610e39578182fd5b50508035926020909101359150565b600060208284031215610e59578081fd5b6106eb8383610d0e565b60008060008060808587031215610e78578384fd5b843567ffffffffffffffff80821115610e8f578586fd5b818701915087601f830112610ea2578586fd5b813581811115610eb0578687fd5b60209150610ec6601f8201601f191683016113bc565b8181528983838601011115610ed9578788fd5b8183850184830137908101820196909652610ef688888301610d03565b94505050610f078660408701610d03565b9150610f168660608701610d03565b905092959194509250565b60008183036060811215610f33578182fd5b610f3d60606113bc565b6020821215610f4a578283fd5b610f5460206113bc565b9150610f608585610d0e565b8252908152602083013590610f748261143b565b81602082015260408401359150610f8a82611450565b60408101919091529392505050565b60008251610fab81846020870161140b565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b600060208252825180602084015261101381604085016020870161140b565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526021908201527f467265657a696e6720737461746573206d75737420626520646966666572656e6040820152601d60fa1b606082015260800190565b60208082526021908201527f536f7572636520636861696e206e616d65206d757374206265204d61696e6e656040820152601d60fa1b606082015260800190565b6020808252601f908201527f4d6573736167652074797065206973206e6f7420467265657a65205573657200604082015260600190565b6020808252601a908201527f526563697069656e74206d75737420626520756e66726f7a656e000000000000604082015260600190565b6020808252601c908201527f53656e646572206d75737420626520436f6d6d756e697479506f6f6c00000000604082015260600190565b60208082526029908201527f546865206d6573736167652073686f756c6420636f6e7461696e20612066726f6040820152687a656e20737461746560b81b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f547279696e6720746f2073656e64206d6573736167657320746f6f206f6674656040820152603760f91b606082015260800190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b6020808252601d908201527f53656e646572206973206e6f742061206d6573736167652070726f7879000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60405181810167ffffffffffffffff811182821017156113db57600080fd5b604052919050565b600080858511156113f2578182fd5b838611156113fe578182fd5b5050820193919092039150565b60005b8381101561142657818101518382015260200161140e565b83811115611435576000848401525b50505050565b6001600160a01b0381168114610aa557600080fd5b8015158114610aa557600080fdfea2646970667358221220a16be2dcea165d37c26d9bebb8c6ad17976baccf1a7ed1cbd6dc1de613a875bf64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/ERC1155OnChain.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/ERC1155OnChain.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/ERC1155OnChain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/ERC1155OnChain.json b/predeployed/build/lib/ima_predeployed/artifacts/ERC1155OnChain.json new file mode 100644 index 000000000..0eb73d7ea --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/ERC1155OnChain.json @@ -0,0 +1,677 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ERC1155OnChain", + "sourceName": "contracts/schain/tokens/ERC1155OnChain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "uri", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "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": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "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": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "burnBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mintBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "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": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b506040516200381938038062003819833981810160405260208110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052505050620001026200017360201b620017601760201c565b62000118816200023160201b620018121760201c565b6200012d620002fb60201b620018cd1760201c565b62000148600080516020620037f983398151915280620003a3565b6200016c600080516020620037f983398151915262000166620003f5565b620003f9565b5062000872565b600054610100900460ff16806200018f57506200018f62000405565b806200019e575060005460ff16155b620001db5760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff1615801562000207576000805460ff1961ff0019909116610100171660011790555b6200021162000423565b6200021b62000423565b80156200022e576000805461ff00191690555b50565b600054610100900460ff16806200024d57506200024d62000405565b806200025c575060005460ff16155b620002995760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff16158015620002c5576000805460ff1961ff0019909116610100171660011790555b620002cf62000423565b620002d9620004cb565b620002e48262000571565b8015620002f7576000805461ff00191690555b5050565b600054610100900460ff16806200031757506200031762000405565b8062000326575060005460ff16155b620003635760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200038f576000805460ff1961ff0019909116610100171660011790555b6200039962000423565b62000211620004cb565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620002f7828262000634565b60006200041d30620006af60201b6200196a1760201c565b15905090565b600054610100900460ff16806200043f57506200043f62000405565b806200044e575060005460ff16155b6200048b5760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200021b576000805460ff1961ff00199091166101001716600117905580156200022e576000805461ff001916905550565b600054610100900460ff1680620004e75750620004e762000405565b80620004f6575060005460ff16155b620005335760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200055f576000805460ff1961ff0019909116610100171660011790555b6200021b6301ffc9a760e01b620006b5565b600054610100900460ff16806200058d57506200058d62000405565b806200059c575060005460ff16155b620005d95760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff1615801562000605576000805460ff1961ff0019909116610100171660011790555b62000610826200073a565b62000622636cdb3d1360e11b620006b5565b620002e46303a24d0760e21b620006b5565b60008281526033602090815260409091206200065b918390620019706200074f821b17901c565b15620002f7576200066b620003f5565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b6001600160e01b0319808216141562000715576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b8051620002f7906099906020840190620007d6565b600062000766836001600160a01b0384166200076f565b90505b92915050565b60006200077d8383620007be565b620007b55750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000769565b50600062000769565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200081957805160ff191683800117855562000849565b8280016001018555821562000849579182015b82811115620008495782518255916020019190600101906200082c565b50620008579291506200085b565b5090565b5b808211156200085757600081556001016200085c565b612f4980620008826000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c87314610a3d578063d539139314610a5a578063d547741f14610a62578063e985e9c514610a8e578063f242432a14610abc578063f5298aca14610b8557610136565b8063731133e9146108dc5780639010d07c1461099c57806391d14854146109db578063a217fddf14610a07578063a22cb46514610a0f57610136565b80632eb2c2d6116100ff5780632eb2c2d61461041d5780632f2ff15d146105de57806336568abe1461060a5780634e1273f4146106365780636b20c454146107a957610136565b8062fdd58e1461013b57806301ffc9a7146101795780630e89341c146101b45780631f7fdffa14610246578063248a9ca314610400575b600080fd5b6101676004803603604081101561015157600080fd5b506001600160a01b038135169060200135610bb7565b60408051918252519081900360200190f35b6101a06004803603602081101561018f57600080fd5b50356001600160e01b031916610c29565b604080519115158252519081900360200190f35b6101d1600480360360208110156101ca57600080fd5b5035610c48565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103fe6004803603608081101561025c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561028657600080fd5b82018360208201111561029857600080fd5b803590602001918460208302840111600160201b831117156102b957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561030857600080fd5b82018360208201111561031a57600080fd5b803590602001918460208302840111600160201b8311171561033b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561038a57600080fd5b82018360208201111561039c57600080fd5b803590602001918460018302840111600160201b831117156103bd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ce0945050505050565b005b6101676004803603602081101561041657600080fd5b5035610d6d565b6103fe600480360360a081101561043357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561046657600080fd5b82018360208201111561047857600080fd5b803590602001918460208302840111600160201b8311171561049957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156104e857600080fd5b8201836020820111156104fa57600080fd5b803590602001918460208302840111600160201b8311171561051b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561056a57600080fd5b82018360208201111561057c57600080fd5b803590602001918460018302840111600160201b8311171561059d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610d82945050505050565b6103fe600480360360408110156105f457600080fd5b50803590602001356001600160a01b0316611085565b6103fe6004803603604081101561062057600080fd5b50803590602001356001600160a01b03166110ec565b6107596004803603604081101561064c57600080fd5b810190602081018135600160201b81111561066657600080fd5b82018360208201111561067857600080fd5b803590602001918460208302840111600160201b8311171561069957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156106e857600080fd5b8201836020820111156106fa57600080fd5b803590602001918460208302840111600160201b8311171561071b57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061114d945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561079557818101518382015260200161077d565b505050509050019250505060405180910390f35b6103fe600480360360608110156107bf57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156107e957600080fd5b8201836020820111156107fb57600080fd5b803590602001918460208302840111600160201b8311171561081c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561086b57600080fd5b82018360208201111561087d57600080fd5b803590602001918460208302840111600160201b8311171561089e57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611239945050505050565b6103fe600480360360808110156108f257600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561092857600080fd5b82018360208201111561093a57600080fd5b803590602001918460018302840111600160201b8311171561095b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506112b2945050505050565b6109bf600480360360408110156109b257600080fd5b5080359060200135611334565b604080516001600160a01b039092168252519081900360200190f35b6101a0600480360360408110156109f157600080fd5b50803590602001356001600160a01b0316611353565b61016761136b565b6103fe60048036036040811015610a2557600080fd5b506001600160a01b0381351690602001351515611370565b61016760048036036020811015610a5357600080fd5b503561145f565b610167611476565b6103fe60048036036040811015610a7857600080fd5b50803590602001356001600160a01b031661149a565b6101a060048036036040811015610aa457600080fd5b506001600160a01b03813581169160200135166114f3565b6103fe600480360360a0811015610ad257600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610b1157600080fd5b820183602082011115610b2357600080fd5b803590602001918460018302840111600160201b83111715610b4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611521945050505050565b6103fe60048036036060811015610b9b57600080fd5b506001600160a01b0381351690602081013590604001356116ec565b60006001600160a01b038316610bfe5760405162461bcd60e51b815260040180806020018281038252602b815260200180612cd0602b913960400191505060405180910390fd5b5060008181526097602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526065602052604090205460ff1690565b60998054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610cd45780601f10610ca957610100808354040283529160200191610cd4565b820191906000526020600020905b815481529060010190602001808311610cb757829003601f168201915b50505050509050919050565b610d117f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611353565b610d5b576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461198a565b50505050565b60009081526033602052604090206002015490565b8151835114610dc25760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6001600160a01b038416610e075760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b610e0f611985565b6001600160a01b0316856001600160a01b03161480610e3a5750610e3a85610e35611985565b6114f3565b610e755760405162461bcd60e51b8152600401808060200182810382526032815260200180612d9d6032913960400191505060405180910390fd5b6000610e7f611985565b9050610e8f81878787878761107d565b60005b8451811015610f95576000858281518110610ea957fe5b602002602001015190506000858381518110610ec157fe5b60200260200101519050610f2e816040518060600160405280602a8152602001612e20602a91396097600086815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b60008381526097602090815260408083206001600160a01b038e811685529252808320939093558a1681522054610f659082611c76565b60009283526097602090815260408085206001600160a01b038c1686529091529092209190915550600101610e92565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561101b578181015183820152602001611003565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561105a578181015183820152602001611042565b5050505090500194505050505060405180910390a461107d818787878787611cd0565b505050505050565b6000828152603360205260409020600201546110a390610d0c611985565b6110de5760405162461bcd60e51b815260040180806020018281038252602f815260200180612ca1602f913960400191505060405180910390fd5b6110e88282611f4f565b5050565b6110f4611985565b6001600160a01b0316816001600160a01b0316146111435760405162461bcd60e51b815260040180806020018281038252602f815260200180612ee5602f913960400191505060405180910390fd5b6110e88282611fb8565b6060815183511461118f5760405162461bcd60e51b8152600401808060200182810382526029815260200180612e736029913960400191505060405180910390fd5b6060835167ffffffffffffffff811180156111a957600080fd5b506040519080825280602002602001820160405280156111d3578160200160208202803683370190505b50905060005b8451811015611231576112128582815181106111f157fe5b602002602001015185838151811061120557fe5b6020026020010151610bb7565b82828151811061121e57fe5b60209081029190910101526001016111d9565b509392505050565b611241611985565b6001600160a01b0316836001600160a01b03161480611267575061126783610e35611985565b6112a25760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612021565b505050565b6112de7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611328576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461228f565b600082815260336020526040812061134c9083612390565b9392505050565b600082815260336020526040812061134c908361239c565b600081565b816001600160a01b0316611382611985565b6001600160a01b031614156113c85760405162461bcd60e51b8152600401808060200182810382526029815260200180612e4a6029913960400191505060405180910390fd5b80609860006113d5611985565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611419611985565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b6000818152603360205260408120610c23906123b1565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6000828152603360205260409020600201546114b890610d0c611985565b6111435760405162461bcd60e51b8152600401808060200182810382526030815260200180612d486030913960400191505060405180910390fd5b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166115665760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b61156e611985565b6001600160a01b0316856001600160a01b03161480611594575061159485610e35611985565b6115cf5760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b60006115d9611985565b90506115f98187876115ea886123bc565b6115f3886123bc565b8761107d565b611640836040518060600160405280602a8152602001612e20602a913960008781526097602090815260408083206001600160a01b038d1684529091529020549190611bdf565b60008581526097602090815260408083206001600160a01b038b811685529252808320939093558716815220546116779084611c76565b60008581526097602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461107d818787878787612400565b6116f4611985565b6001600160a01b0316836001600160a01b0316148061171a575061171a83610e35611985565b6117555760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612571565b600054610100900460ff168061177957506117796126a4565b80611787575060005460ff16155b6117c25760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117ed576000805460ff1961ff0019909116610100171660011790555b6117f56126b5565b6117fd6126b5565b801561180f576000805461ff00191690555b50565b600054610100900460ff168061182b575061182b6126a4565b80611839575060005460ff16155b6118745760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561189f576000805460ff1961ff0019909116610100171660011790555b6118a76126b5565b6118af612755565b6118b8826127f2565b80156110e8576000805461ff00191690555050565b600054610100900460ff16806118e657506118e66126a4565b806118f4575060005460ff16155b61192f5760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561195a576000805460ff1961ff0019909116610100171660011790555b6119626126b5565b6117f5612755565b3b151590565b600061134c836001600160a01b0384166128a8565b335b90565b6001600160a01b0384166119cf5760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b8151835114611a0f5760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6000611a19611985565b9050611a2a8160008787878761107d565b60005b8451811015611aee57611aa560976000878481518110611a4957fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002054858381518110611a8f57fe5b6020026020010151611c7690919063ffffffff16565b60976000878481518110611ab557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101611a2d565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015611b75578181015183820152602001611b5d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015611bb4578181015183820152602001611b9c565b5050505090500194505050505060405180910390a4611bd881600087878787611cd0565b5050505050565b60008184841115611c6e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c33578181015183820152602001611c1b565b50505050905090810190601f168015611c605780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008282018381101561134c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b611ce2846001600160a01b031661196a565b1561107d57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015611d70578181015183820152602001611d58565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015611daf578181015183820152602001611d97565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015611deb578181015183820152602001611dd3565b50505050905090810190601f168015611e185780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b158015611e3d57600080fd5b505af1925050508015611e6257506040513d6020811015611e5d57600080fd5b505160015b611ef757611e6e612b7d565b80611e795750611ec0565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315611c33578181015183820152602001611c1b565b60405162461bcd60e51b8152600401808060200182810382526034815260200180612c236034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b50505050505050565b6000828152603360205260409020611f679082611970565b156110e857611f74611985565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020611fd090826128f2565b156110e857611fdd611985565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b0383166120665760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b80518251146120a65760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b60006120b0611985565b90506120d08185600086866040518060200160405280600081525061107d565b60005b83518110156121ae576121658382815181106120eb57fe5b6020026020010151604051806060016040528060248152602001612cfb602491396097600088868151811061211c57fe5b602002602001015181526020019081526020016000206000896001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b6097600086848151811061217557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038a1682529092529020556001016120d3565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561223557818101518382015260200161221d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561227457818101518382015260200161225c565b5050505090500194505050505060405180910390a450505050565b6001600160a01b0384166122d45760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b60006122de611985565b90506122f0816000876115ea886123bc565b60008481526097602090815260408083206001600160a01b038916845290915290205461231d9084611c76565b60008581526097602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a4611bd881600087878787612400565b600061134c8383612907565b600061134c836001600160a01b03841661296b565b6000610c2382612983565b6040805160018082528183019092526060918291906020808301908036833701905050905082816000815181106123ef57fe5b602090810291909101015292915050565b612412846001600160a01b031661196a565b1561107d57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156124a1578181015183820152602001612489565b50505050905090810190601f1680156124ce5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b1580156124f157600080fd5b505af192505050801561251657506040513d602081101561251157600080fd5b505160015b61252257611e6e612b7d565b6001600160e01b0319811663f23a6e6160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b6001600160a01b0383166125b65760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b60006125c0611985565b90506125f0818560006125d2876123bc565b6125db876123bc565b6040518060200160405280600081525061107d565b61263782604051806060016040528060248152602001612cfb6024913960008681526097602090815260408083206001600160a01b038b1684529091529020549190611bdf565b60008481526097602090815260408083206001600160a01b03808a16808652918452828520959095558151888152928301879052815193949093908616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a450505050565b60006126af3061196a565b15905090565b600054610100900460ff16806126ce57506126ce6126a4565b806126dc575060005460ff16155b6127175760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117fd576000805460ff1961ff001990911661010017166001179055801561180f576000805461ff001916905550565b600054610100900460ff168061276e575061276e6126a4565b8061277c575060005460ff16155b6127b75760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156127e2576000805460ff1961ff0019909116610100171660011790555b6117fd6301ffc9a760e01b612987565b600054610100900460ff168061280b575061280b6126a4565b80612819575060005460ff16155b6128545760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561287f576000805460ff1961ff0019909116610100171660011790555b61288882612a0b565b612898636cdb3d1360e11b612987565b6118b86303a24d0760e21b612987565b60006128b4838361296b565b6128ea57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c23565b506000610c23565b600061134c836001600160a01b038416612a1e565b815460009082106129495760405162461bcd60e51b8152600401808060200182810382526022815260200180612c576022913960400191505060405180910390fd5b82600001828154811061295857fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6001600160e01b031980821614156129e6576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b80516110e8906099906020840190612ae4565b60008181526001830160205260408120548015612ada5783546000198083019190810190600090879083908110612a5157fe5b9060005260206000200154905080876000018481548110612a6e57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612a9e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610c23565b6000915050610c23565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612b2557805160ff1916838001178555612b52565b82800160010185558215612b52579182015b82811115612b52578251825591602001919060010190612b37565b50612b5e929150612b62565b5090565b5b80821115612b5e5760008155600101612b63565b60e01c90565b600060443d1015612b8d57611987565b600481823e6308c379a0612ba18251612b77565b14612bab57611987565b6040513d600319016004823e80513d67ffffffffffffffff8160248401118184111715612bdb5750505050611987565b82840192508251915080821115612bf55750505050611987565b503d83016020828401011115612c0d57505050611987565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e746572456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e73416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373455243313135353a206275726e20616d6f756e7420657863656564732062616c616e6365455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564455243313135353a206275726e2066726f6d20746865207a65726f2061646472657373455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d61746368455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212208082e80af5715fe3fac7824ad3b116a08ca0bb914f0d3fd373b87d6d3d635c7664736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c87314610a3d578063d539139314610a5a578063d547741f14610a62578063e985e9c514610a8e578063f242432a14610abc578063f5298aca14610b8557610136565b8063731133e9146108dc5780639010d07c1461099c57806391d14854146109db578063a217fddf14610a07578063a22cb46514610a0f57610136565b80632eb2c2d6116100ff5780632eb2c2d61461041d5780632f2ff15d146105de57806336568abe1461060a5780634e1273f4146106365780636b20c454146107a957610136565b8062fdd58e1461013b57806301ffc9a7146101795780630e89341c146101b45780631f7fdffa14610246578063248a9ca314610400575b600080fd5b6101676004803603604081101561015157600080fd5b506001600160a01b038135169060200135610bb7565b60408051918252519081900360200190f35b6101a06004803603602081101561018f57600080fd5b50356001600160e01b031916610c29565b604080519115158252519081900360200190f35b6101d1600480360360208110156101ca57600080fd5b5035610c48565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103fe6004803603608081101561025c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561028657600080fd5b82018360208201111561029857600080fd5b803590602001918460208302840111600160201b831117156102b957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561030857600080fd5b82018360208201111561031a57600080fd5b803590602001918460208302840111600160201b8311171561033b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561038a57600080fd5b82018360208201111561039c57600080fd5b803590602001918460018302840111600160201b831117156103bd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ce0945050505050565b005b6101676004803603602081101561041657600080fd5b5035610d6d565b6103fe600480360360a081101561043357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561046657600080fd5b82018360208201111561047857600080fd5b803590602001918460208302840111600160201b8311171561049957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156104e857600080fd5b8201836020820111156104fa57600080fd5b803590602001918460208302840111600160201b8311171561051b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561056a57600080fd5b82018360208201111561057c57600080fd5b803590602001918460018302840111600160201b8311171561059d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610d82945050505050565b6103fe600480360360408110156105f457600080fd5b50803590602001356001600160a01b0316611085565b6103fe6004803603604081101561062057600080fd5b50803590602001356001600160a01b03166110ec565b6107596004803603604081101561064c57600080fd5b810190602081018135600160201b81111561066657600080fd5b82018360208201111561067857600080fd5b803590602001918460208302840111600160201b8311171561069957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156106e857600080fd5b8201836020820111156106fa57600080fd5b803590602001918460208302840111600160201b8311171561071b57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061114d945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561079557818101518382015260200161077d565b505050509050019250505060405180910390f35b6103fe600480360360608110156107bf57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156107e957600080fd5b8201836020820111156107fb57600080fd5b803590602001918460208302840111600160201b8311171561081c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561086b57600080fd5b82018360208201111561087d57600080fd5b803590602001918460208302840111600160201b8311171561089e57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611239945050505050565b6103fe600480360360808110156108f257600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561092857600080fd5b82018360208201111561093a57600080fd5b803590602001918460018302840111600160201b8311171561095b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506112b2945050505050565b6109bf600480360360408110156109b257600080fd5b5080359060200135611334565b604080516001600160a01b039092168252519081900360200190f35b6101a0600480360360408110156109f157600080fd5b50803590602001356001600160a01b0316611353565b61016761136b565b6103fe60048036036040811015610a2557600080fd5b506001600160a01b0381351690602001351515611370565b61016760048036036020811015610a5357600080fd5b503561145f565b610167611476565b6103fe60048036036040811015610a7857600080fd5b50803590602001356001600160a01b031661149a565b6101a060048036036040811015610aa457600080fd5b506001600160a01b03813581169160200135166114f3565b6103fe600480360360a0811015610ad257600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610b1157600080fd5b820183602082011115610b2357600080fd5b803590602001918460018302840111600160201b83111715610b4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611521945050505050565b6103fe60048036036060811015610b9b57600080fd5b506001600160a01b0381351690602081013590604001356116ec565b60006001600160a01b038316610bfe5760405162461bcd60e51b815260040180806020018281038252602b815260200180612cd0602b913960400191505060405180910390fd5b5060008181526097602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526065602052604090205460ff1690565b60998054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610cd45780601f10610ca957610100808354040283529160200191610cd4565b820191906000526020600020905b815481529060010190602001808311610cb757829003601f168201915b50505050509050919050565b610d117f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611353565b610d5b576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461198a565b50505050565b60009081526033602052604090206002015490565b8151835114610dc25760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6001600160a01b038416610e075760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b610e0f611985565b6001600160a01b0316856001600160a01b03161480610e3a5750610e3a85610e35611985565b6114f3565b610e755760405162461bcd60e51b8152600401808060200182810382526032815260200180612d9d6032913960400191505060405180910390fd5b6000610e7f611985565b9050610e8f81878787878761107d565b60005b8451811015610f95576000858281518110610ea957fe5b602002602001015190506000858381518110610ec157fe5b60200260200101519050610f2e816040518060600160405280602a8152602001612e20602a91396097600086815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b60008381526097602090815260408083206001600160a01b038e811685529252808320939093558a1681522054610f659082611c76565b60009283526097602090815260408085206001600160a01b038c1686529091529092209190915550600101610e92565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561101b578181015183820152602001611003565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561105a578181015183820152602001611042565b5050505090500194505050505060405180910390a461107d818787878787611cd0565b505050505050565b6000828152603360205260409020600201546110a390610d0c611985565b6110de5760405162461bcd60e51b815260040180806020018281038252602f815260200180612ca1602f913960400191505060405180910390fd5b6110e88282611f4f565b5050565b6110f4611985565b6001600160a01b0316816001600160a01b0316146111435760405162461bcd60e51b815260040180806020018281038252602f815260200180612ee5602f913960400191505060405180910390fd5b6110e88282611fb8565b6060815183511461118f5760405162461bcd60e51b8152600401808060200182810382526029815260200180612e736029913960400191505060405180910390fd5b6060835167ffffffffffffffff811180156111a957600080fd5b506040519080825280602002602001820160405280156111d3578160200160208202803683370190505b50905060005b8451811015611231576112128582815181106111f157fe5b602002602001015185838151811061120557fe5b6020026020010151610bb7565b82828151811061121e57fe5b60209081029190910101526001016111d9565b509392505050565b611241611985565b6001600160a01b0316836001600160a01b03161480611267575061126783610e35611985565b6112a25760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612021565b505050565b6112de7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611328576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461228f565b600082815260336020526040812061134c9083612390565b9392505050565b600082815260336020526040812061134c908361239c565b600081565b816001600160a01b0316611382611985565b6001600160a01b031614156113c85760405162461bcd60e51b8152600401808060200182810382526029815260200180612e4a6029913960400191505060405180910390fd5b80609860006113d5611985565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611419611985565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b6000818152603360205260408120610c23906123b1565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6000828152603360205260409020600201546114b890610d0c611985565b6111435760405162461bcd60e51b8152600401808060200182810382526030815260200180612d486030913960400191505060405180910390fd5b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166115665760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b61156e611985565b6001600160a01b0316856001600160a01b03161480611594575061159485610e35611985565b6115cf5760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b60006115d9611985565b90506115f98187876115ea886123bc565b6115f3886123bc565b8761107d565b611640836040518060600160405280602a8152602001612e20602a913960008781526097602090815260408083206001600160a01b038d1684529091529020549190611bdf565b60008581526097602090815260408083206001600160a01b038b811685529252808320939093558716815220546116779084611c76565b60008581526097602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461107d818787878787612400565b6116f4611985565b6001600160a01b0316836001600160a01b0316148061171a575061171a83610e35611985565b6117555760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612571565b600054610100900460ff168061177957506117796126a4565b80611787575060005460ff16155b6117c25760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117ed576000805460ff1961ff0019909116610100171660011790555b6117f56126b5565b6117fd6126b5565b801561180f576000805461ff00191690555b50565b600054610100900460ff168061182b575061182b6126a4565b80611839575060005460ff16155b6118745760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561189f576000805460ff1961ff0019909116610100171660011790555b6118a76126b5565b6118af612755565b6118b8826127f2565b80156110e8576000805461ff00191690555050565b600054610100900460ff16806118e657506118e66126a4565b806118f4575060005460ff16155b61192f5760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561195a576000805460ff1961ff0019909116610100171660011790555b6119626126b5565b6117f5612755565b3b151590565b600061134c836001600160a01b0384166128a8565b335b90565b6001600160a01b0384166119cf5760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b8151835114611a0f5760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6000611a19611985565b9050611a2a8160008787878761107d565b60005b8451811015611aee57611aa560976000878481518110611a4957fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002054858381518110611a8f57fe5b6020026020010151611c7690919063ffffffff16565b60976000878481518110611ab557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101611a2d565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015611b75578181015183820152602001611b5d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015611bb4578181015183820152602001611b9c565b5050505090500194505050505060405180910390a4611bd881600087878787611cd0565b5050505050565b60008184841115611c6e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c33578181015183820152602001611c1b565b50505050905090810190601f168015611c605780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008282018381101561134c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b611ce2846001600160a01b031661196a565b1561107d57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015611d70578181015183820152602001611d58565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015611daf578181015183820152602001611d97565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015611deb578181015183820152602001611dd3565b50505050905090810190601f168015611e185780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b158015611e3d57600080fd5b505af1925050508015611e6257506040513d6020811015611e5d57600080fd5b505160015b611ef757611e6e612b7d565b80611e795750611ec0565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315611c33578181015183820152602001611c1b565b60405162461bcd60e51b8152600401808060200182810382526034815260200180612c236034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b50505050505050565b6000828152603360205260409020611f679082611970565b156110e857611f74611985565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020611fd090826128f2565b156110e857611fdd611985565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b0383166120665760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b80518251146120a65760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b60006120b0611985565b90506120d08185600086866040518060200160405280600081525061107d565b60005b83518110156121ae576121658382815181106120eb57fe5b6020026020010151604051806060016040528060248152602001612cfb602491396097600088868151811061211c57fe5b602002602001015181526020019081526020016000206000896001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b6097600086848151811061217557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038a1682529092529020556001016120d3565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561223557818101518382015260200161221d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561227457818101518382015260200161225c565b5050505090500194505050505060405180910390a450505050565b6001600160a01b0384166122d45760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b60006122de611985565b90506122f0816000876115ea886123bc565b60008481526097602090815260408083206001600160a01b038916845290915290205461231d9084611c76565b60008581526097602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a4611bd881600087878787612400565b600061134c8383612907565b600061134c836001600160a01b03841661296b565b6000610c2382612983565b6040805160018082528183019092526060918291906020808301908036833701905050905082816000815181106123ef57fe5b602090810291909101015292915050565b612412846001600160a01b031661196a565b1561107d57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156124a1578181015183820152602001612489565b50505050905090810190601f1680156124ce5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b1580156124f157600080fd5b505af192505050801561251657506040513d602081101561251157600080fd5b505160015b61252257611e6e612b7d565b6001600160e01b0319811663f23a6e6160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b6001600160a01b0383166125b65760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b60006125c0611985565b90506125f0818560006125d2876123bc565b6125db876123bc565b6040518060200160405280600081525061107d565b61263782604051806060016040528060248152602001612cfb6024913960008681526097602090815260408083206001600160a01b038b1684529091529020549190611bdf565b60008481526097602090815260408083206001600160a01b03808a16808652918452828520959095558151888152928301879052815193949093908616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a450505050565b60006126af3061196a565b15905090565b600054610100900460ff16806126ce57506126ce6126a4565b806126dc575060005460ff16155b6127175760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117fd576000805460ff1961ff001990911661010017166001179055801561180f576000805461ff001916905550565b600054610100900460ff168061276e575061276e6126a4565b8061277c575060005460ff16155b6127b75760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156127e2576000805460ff1961ff0019909116610100171660011790555b6117fd6301ffc9a760e01b612987565b600054610100900460ff168061280b575061280b6126a4565b80612819575060005460ff16155b6128545760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561287f576000805460ff1961ff0019909116610100171660011790555b61288882612a0b565b612898636cdb3d1360e11b612987565b6118b86303a24d0760e21b612987565b60006128b4838361296b565b6128ea57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c23565b506000610c23565b600061134c836001600160a01b038416612a1e565b815460009082106129495760405162461bcd60e51b8152600401808060200182810382526022815260200180612c576022913960400191505060405180910390fd5b82600001828154811061295857fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6001600160e01b031980821614156129e6576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b80516110e8906099906020840190612ae4565b60008181526001830160205260408120548015612ada5783546000198083019190810190600090879083908110612a5157fe5b9060005260206000200154905080876000018481548110612a6e57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612a9e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610c23565b6000915050610c23565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612b2557805160ff1916838001178555612b52565b82800160010185558215612b52579182015b82811115612b52578251825591602001919060010190612b37565b50612b5e929150612b62565b5090565b5b80821115612b5e5760008155600101612b63565b60e01c90565b600060443d1015612b8d57611987565b600481823e6308c379a0612ba18251612b77565b14612bab57611987565b6040513d600319016004823e80513d67ffffffffffffffff8160248401118184111715612bdb5750505050611987565b82840192508251915080821115612bf55750505050611987565b503d83016020828401011115612c0d57505050611987565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e746572456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e73416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373455243313135353a206275726e20616d6f756e7420657863656564732062616c616e6365455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564455243313135353a206275726e2066726f6d20746865207a65726f2061646472657373455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d61746368455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212208082e80af5715fe3fac7824ad3b116a08ca0bb914f0d3fd373b87d6d3d635c7664736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/ERC20OnChain.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/ERC20OnChain.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/ERC20OnChain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/ERC20OnChain.json b/predeployed/build/lib/ima_predeployed/artifacts/ERC20OnChain.json new file mode 100644 index 000000000..3c0b7f0ee --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/ERC20OnChain.json @@ -0,0 +1,587 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ERC20OnChain", + "sourceName": "contracts/schain/tokens/ERC20OnChain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "contractName", + "type": "string" + }, + { + "internalType": "string", + "name": "contractSymbol", + "type": "string" + } + ], + "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": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "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": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "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": "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" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b506040516200206638038062002066833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604052505050620001b46200022760201b62000a681760201c565b620001cb8282620002e560201b62000b191760201c565b620001e06200022760201b62000a681760201c565b620001fb6000805160206200204683398151915280620003a7565b6200021f6000805160206200204683398151915262000219620003f9565b620003fd565b50506200075b565b600054610100900460ff1680620002435750620002436200040d565b8062000252575060005460ff16155b6200028f5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff16158015620002bb576000805460ff1961ff0019909116610100171660011790555b620002c56200042b565b620002cf6200042b565b8015620002e2576000805461ff00191690555b50565b600054610100900460ff1680620003015750620003016200040d565b8062000310575060005460ff16155b6200034d5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff1615801562000379576000805460ff1961ff0019909116610100171660011790555b620003836200042b565b6200038f8383620004d3565b8015620003a2576000805461ff00191690555b505050565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620004098282620005b7565b5050565b600062000425306200063260201b62000bce1760201c565b15905090565b600054610100900460ff1680620004475750620004476200040d565b8062000456575060005460ff16155b620004935760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff16158015620002cf576000805460ff1961ff0019909116610100171660011790558015620002e2576000805461ff001916905550565b600054610100900460ff1680620004ef5750620004ef6200040d565b80620004fe575060005460ff16155b6200053b5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff1615801562000567576000805460ff1961ff0019909116610100171660011790555b82516200057c906068906020860190620006bf565b50815162000592906069906020850190620006bf565b50606a805460ff191660121790558015620003a2576000805461ff0019169055505050565b6000828152603360209081526040909120620005de91839062000bd462000638821b17901c565b156200040957620005ee620003f9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b60006200064f836001600160a01b03841662000658565b90505b92915050565b6000620006668383620006a7565b6200069e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000652565b50600062000652565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200070257805160ff191683800117855562000732565b8280016001018555821562000732579182015b828111156200073257825182559160200191906001019062000715565b506200074092915062000744565b5090565b5b8082111562000740576000815560010162000745565b6118ad806200076b6000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d714610436578063a9059cbb14610462578063ca15c8731461048e578063d5391393146104ab578063d547741f146104b3578063dd62ed3e146104df5761014d565b806370a082311461036957806379cc67901461038f5780639010d07c146103bb57806391d14854146103fa57806395d89b4114610426578063a217fddf1461042e5761014d565b80632f2ff15d116101155780632f2ff15d1461027c578063313ce567146102aa57806336568abe146102c857806339509351146102f457806340c10f191461032057806342966c681461034c5761014d565b806306fdde0314610152578063095ea7b3146101cf57806318160ddd1461020f57806323b872dd14610229578063248a9ca31461025f575b600080fd5b61015a61050d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561019457818101518382015260200161017c565b50505050905090810190601f1680156101c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101fb600480360360408110156101e557600080fd5b506001600160a01b0381351690602001356105a3565b604080519115158252519081900360200190f35b6102176105c1565b60408051918252519081900360200190f35b6101fb6004803603606081101561023f57600080fd5b506001600160a01b038135811691602081013590911690604001356105c7565b6102176004803603602081101561027557600080fd5b503561064e565b6102a86004803603604081101561029257600080fd5b50803590602001356001600160a01b0316610663565b005b6102b26106cf565b6040805160ff9092168252519081900360200190f35b6102a8600480360360408110156102de57600080fd5b50803590602001356001600160a01b03166106d8565b6101fb6004803603604081101561030a57600080fd5b506001600160a01b038135169060200135610739565b6102a86004803603604081101561033657600080fd5b506001600160a01b038135169060200135610787565b6102a86004803603602081101561036257600080fd5b5035610807565b6102176004803603602081101561037f57600080fd5b50356001600160a01b031661081b565b6102a8600480360360408110156103a557600080fd5b506001600160a01b038135169060200135610836565b6103de600480360360408110156103d157600080fd5b5080359060200135610890565b604080516001600160a01b039092168252519081900360200190f35b6101fb6004803603604081101561041057600080fd5b50803590602001356001600160a01b03166108af565b61015a6108c7565b610217610928565b6101fb6004803603604081101561044c57600080fd5b506001600160a01b03813516906020013561092d565b6101fb6004803603604081101561047857600080fd5b506001600160a01b038135169060200135610995565b610217600480360360208110156104a457600080fd5b50356109a9565b6102176109c0565b6102a8600480360360408110156104c957600080fd5b50803590602001356001600160a01b03166109e4565b610217600480360360408110156104f557600080fd5b506001600160a01b0381358116916020013516610a3d565b60688054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b820191906000526020600020905b81548152906001019060200180831161057c57829003601f168201915b5050505050905090565b60006105b76105b0610be9565b8484610bed565b5060015b92915050565b60675490565b60006105d4848484610cd9565b610644846105e0610be9565b61063f8560405180606001604052806028815260200161176e602891396001600160a01b038a1660009081526066602052604081209061061e610be9565b6001600160a01b031681526020810191909152604001600020549190610e36565b610bed565b5060019392505050565b60009081526033602052604090206002015490565b60008281526033602052604090206002015461068690610681610be9565b6108af565b6106c15760405162461bcd60e51b815260040180806020018281038252602f815260200180611677602f913960400191505060405180910390fd5b6106cb8282610ecd565b5050565b606a5460ff1690565b6106e0610be9565b6001600160a01b0316816001600160a01b03161461072f5760405162461bcd60e51b815260040180806020018281038252602f815260200180611849602f913960400191505060405180910390fd5b6106cb8282610f36565b60006105b7610746610be9565b8461063f8560666000610757610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610f9f565b6107b37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610681610be9565b6107fd576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b6106cb8282610ff9565b610818610812610be9565b826110eb565b50565b6001600160a01b031660009081526065602052604090205490565b600061086d826040518060600160405280602481526020016117966024913961086686610861610be9565b610a3d565b9190610e36565b90506108818361087b610be9565b83610bed565b61088b83836110eb565b505050565b60008281526033602052604081206108a890836111e7565b9392505050565b60008281526033602052604081206108a890836111f3565b60698054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b600081565b60006105b761093a610be9565b8461063f856040518060600160405280602581526020016118246025913960666000610964610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610e36565b60006105b76109a2610be9565b8484610cd9565b60008181526033602052604081206105bb90611208565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b600082815260336020526040902060020154610a0290610681610be9565b61072f5760405162461bcd60e51b81526004018080602001828103825260308152602001806117106030913960400191505060405180910390fd5b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b600054610100900460ff1680610a815750610a81611213565b80610a8f575060005460ff16155b610aca5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610af5576000805460ff1961ff0019909116610100171660011790555b610afd611224565b610b05611224565b8015610818576000805461ff001916905550565b600054610100900460ff1680610b325750610b32611213565b80610b40575060005460ff16155b610b7b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610ba6576000805460ff1961ff0019909116610100171660011790555b610bae611224565b610bb883836112c4565b801561088b576000805461ff0019169055505050565b3b151590565b60006108a8836001600160a01b03841661139c565b3390565b6001600160a01b038316610c325760405162461bcd60e51b81526004018080602001828103825260248152602001806118006024913960400191505060405180910390fd5b6001600160a01b038216610c775760405162461bcd60e51b81526004018080602001828103825260228152602001806116c86022913960400191505060405180910390fd5b6001600160a01b03808416600081815260666020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610d1e5760405162461bcd60e51b81526004018080602001828103825260258152602001806117db6025913960400191505060405180910390fd5b6001600160a01b038216610d635760405162461bcd60e51b81526004018080602001828103825260238152602001806116546023913960400191505060405180910390fd5b610d6e83838361088b565b610dab816040518060600160405280602681526020016116ea602691396001600160a01b0386166000908152606560205260409020549190610e36565b6001600160a01b038085166000908152606560205260408082209390935590841681522054610dda9082610f9f565b6001600160a01b0380841660008181526065602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610ec55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610e8a578181015183820152602001610e72565b50505050905090810190601f168015610eb75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828152603360205260409020610ee59082610bd4565b156106cb57610ef2610be9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020610f4e90826113e6565b156106cb57610f5b610be9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000828201838110156108a8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216611054576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6110606000838361088b565b60675461106d9082610f9f565b6067556001600160a01b0382166000908152606560205260409020546110939082610f9f565b6001600160a01b03831660008181526065602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b0382166111305760405162461bcd60e51b81526004018080602001828103825260218152602001806117ba6021913960400191505060405180910390fd5b61113c8260008361088b565b611179816040518060600160405280602281526020016116a6602291396001600160a01b0385166000908152606560205260409020549190610e36565b6001600160a01b03831660009081526065602052604090205560675461119f90826113fb565b6067556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60006108a88383611458565b60006108a8836001600160a01b0384166114bc565b60006105bb826114d4565b600061121e30610bce565b15905090565b600054610100900460ff168061123d575061123d611213565b8061124b575060005460ff16155b6112865760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610b05576000805460ff1961ff0019909116610100171660011790558015610818576000805461ff001916905550565b600054610100900460ff16806112dd57506112dd611213565b806112eb575060005460ff16155b6113265760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015611351576000805460ff1961ff0019909116610100171660011790555b825161136490606890602086019061159e565b50815161137890606990602085019061159e565b50606a805460ff19166012179055801561088b576000805461ff0019169055505050565b60006113a883836114bc565b6113de575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bb565b5060006105bb565b60006108a8836001600160a01b0384166114d8565b600082821115611452576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b8154600090821061149a5760405162461bcd60e51b81526004018080602001828103825260228152602001806116326022913960400191505060405180910390fd5b8260000182815481106114a957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60008181526001830160205260408120548015611594578354600019808301919081019060009087908390811061150b57fe5b906000526020600020015490508087600001848154811061152857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061155857fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506105bb565b60009150506105bb565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106115df57805160ff191683800117855561160c565b8280016001018555821561160c579182015b8281111561160c5782518255916020019190600101906115f1565b5061161892915061161c565b5090565b5b80821115611618576000815560010161161d56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7445524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220f5fd5b9f427fa0188f9574676da4de58e3fd195487cc5f2ba14cd5cbd4d68d2464736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d714610436578063a9059cbb14610462578063ca15c8731461048e578063d5391393146104ab578063d547741f146104b3578063dd62ed3e146104df5761014d565b806370a082311461036957806379cc67901461038f5780639010d07c146103bb57806391d14854146103fa57806395d89b4114610426578063a217fddf1461042e5761014d565b80632f2ff15d116101155780632f2ff15d1461027c578063313ce567146102aa57806336568abe146102c857806339509351146102f457806340c10f191461032057806342966c681461034c5761014d565b806306fdde0314610152578063095ea7b3146101cf57806318160ddd1461020f57806323b872dd14610229578063248a9ca31461025f575b600080fd5b61015a61050d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561019457818101518382015260200161017c565b50505050905090810190601f1680156101c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101fb600480360360408110156101e557600080fd5b506001600160a01b0381351690602001356105a3565b604080519115158252519081900360200190f35b6102176105c1565b60408051918252519081900360200190f35b6101fb6004803603606081101561023f57600080fd5b506001600160a01b038135811691602081013590911690604001356105c7565b6102176004803603602081101561027557600080fd5b503561064e565b6102a86004803603604081101561029257600080fd5b50803590602001356001600160a01b0316610663565b005b6102b26106cf565b6040805160ff9092168252519081900360200190f35b6102a8600480360360408110156102de57600080fd5b50803590602001356001600160a01b03166106d8565b6101fb6004803603604081101561030a57600080fd5b506001600160a01b038135169060200135610739565b6102a86004803603604081101561033657600080fd5b506001600160a01b038135169060200135610787565b6102a86004803603602081101561036257600080fd5b5035610807565b6102176004803603602081101561037f57600080fd5b50356001600160a01b031661081b565b6102a8600480360360408110156103a557600080fd5b506001600160a01b038135169060200135610836565b6103de600480360360408110156103d157600080fd5b5080359060200135610890565b604080516001600160a01b039092168252519081900360200190f35b6101fb6004803603604081101561041057600080fd5b50803590602001356001600160a01b03166108af565b61015a6108c7565b610217610928565b6101fb6004803603604081101561044c57600080fd5b506001600160a01b03813516906020013561092d565b6101fb6004803603604081101561047857600080fd5b506001600160a01b038135169060200135610995565b610217600480360360208110156104a457600080fd5b50356109a9565b6102176109c0565b6102a8600480360360408110156104c957600080fd5b50803590602001356001600160a01b03166109e4565b610217600480360360408110156104f557600080fd5b506001600160a01b0381358116916020013516610a3d565b60688054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b820191906000526020600020905b81548152906001019060200180831161057c57829003601f168201915b5050505050905090565b60006105b76105b0610be9565b8484610bed565b5060015b92915050565b60675490565b60006105d4848484610cd9565b610644846105e0610be9565b61063f8560405180606001604052806028815260200161176e602891396001600160a01b038a1660009081526066602052604081209061061e610be9565b6001600160a01b031681526020810191909152604001600020549190610e36565b610bed565b5060019392505050565b60009081526033602052604090206002015490565b60008281526033602052604090206002015461068690610681610be9565b6108af565b6106c15760405162461bcd60e51b815260040180806020018281038252602f815260200180611677602f913960400191505060405180910390fd5b6106cb8282610ecd565b5050565b606a5460ff1690565b6106e0610be9565b6001600160a01b0316816001600160a01b03161461072f5760405162461bcd60e51b815260040180806020018281038252602f815260200180611849602f913960400191505060405180910390fd5b6106cb8282610f36565b60006105b7610746610be9565b8461063f8560666000610757610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610f9f565b6107b37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610681610be9565b6107fd576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b6106cb8282610ff9565b610818610812610be9565b826110eb565b50565b6001600160a01b031660009081526065602052604090205490565b600061086d826040518060600160405280602481526020016117966024913961086686610861610be9565b610a3d565b9190610e36565b90506108818361087b610be9565b83610bed565b61088b83836110eb565b505050565b60008281526033602052604081206108a890836111e7565b9392505050565b60008281526033602052604081206108a890836111f3565b60698054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b600081565b60006105b761093a610be9565b8461063f856040518060600160405280602581526020016118246025913960666000610964610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610e36565b60006105b76109a2610be9565b8484610cd9565b60008181526033602052604081206105bb90611208565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b600082815260336020526040902060020154610a0290610681610be9565b61072f5760405162461bcd60e51b81526004018080602001828103825260308152602001806117106030913960400191505060405180910390fd5b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b600054610100900460ff1680610a815750610a81611213565b80610a8f575060005460ff16155b610aca5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610af5576000805460ff1961ff0019909116610100171660011790555b610afd611224565b610b05611224565b8015610818576000805461ff001916905550565b600054610100900460ff1680610b325750610b32611213565b80610b40575060005460ff16155b610b7b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610ba6576000805460ff1961ff0019909116610100171660011790555b610bae611224565b610bb883836112c4565b801561088b576000805461ff0019169055505050565b3b151590565b60006108a8836001600160a01b03841661139c565b3390565b6001600160a01b038316610c325760405162461bcd60e51b81526004018080602001828103825260248152602001806118006024913960400191505060405180910390fd5b6001600160a01b038216610c775760405162461bcd60e51b81526004018080602001828103825260228152602001806116c86022913960400191505060405180910390fd5b6001600160a01b03808416600081815260666020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610d1e5760405162461bcd60e51b81526004018080602001828103825260258152602001806117db6025913960400191505060405180910390fd5b6001600160a01b038216610d635760405162461bcd60e51b81526004018080602001828103825260238152602001806116546023913960400191505060405180910390fd5b610d6e83838361088b565b610dab816040518060600160405280602681526020016116ea602691396001600160a01b0386166000908152606560205260409020549190610e36565b6001600160a01b038085166000908152606560205260408082209390935590841681522054610dda9082610f9f565b6001600160a01b0380841660008181526065602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610ec55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610e8a578181015183820152602001610e72565b50505050905090810190601f168015610eb75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828152603360205260409020610ee59082610bd4565b156106cb57610ef2610be9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020610f4e90826113e6565b156106cb57610f5b610be9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000828201838110156108a8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216611054576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6110606000838361088b565b60675461106d9082610f9f565b6067556001600160a01b0382166000908152606560205260409020546110939082610f9f565b6001600160a01b03831660008181526065602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b0382166111305760405162461bcd60e51b81526004018080602001828103825260218152602001806117ba6021913960400191505060405180910390fd5b61113c8260008361088b565b611179816040518060600160405280602281526020016116a6602291396001600160a01b0385166000908152606560205260409020549190610e36565b6001600160a01b03831660009081526065602052604090205560675461119f90826113fb565b6067556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60006108a88383611458565b60006108a8836001600160a01b0384166114bc565b60006105bb826114d4565b600061121e30610bce565b15905090565b600054610100900460ff168061123d575061123d611213565b8061124b575060005460ff16155b6112865760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610b05576000805460ff1961ff0019909116610100171660011790558015610818576000805461ff001916905550565b600054610100900460ff16806112dd57506112dd611213565b806112eb575060005460ff16155b6113265760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015611351576000805460ff1961ff0019909116610100171660011790555b825161136490606890602086019061159e565b50815161137890606990602085019061159e565b50606a805460ff19166012179055801561088b576000805461ff0019169055505050565b60006113a883836114bc565b6113de575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bb565b5060006105bb565b60006108a8836001600160a01b0384166114d8565b600082821115611452576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b8154600090821061149a5760405162461bcd60e51b81526004018080602001828103825260228152602001806116326022913960400191505060405180910390fd5b8260000182815481106114a957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60008181526001830160205260408120548015611594578354600019808301919081019060009087908390811061150b57fe5b906000526020600020015490508087600001848154811061152857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061155857fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506105bb565b60009150506105bb565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106115df57805160ff191683800117855561160c565b8280016001018555821561160c579182015b8281111561160c5782518255916020019190600101906115f1565b5061161892915061161c565b5090565b5b80821115611618576000815560010161161d56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7445524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220f5fd5b9f427fa0188f9574676da4de58e3fd195487cc5f2ba14cd5cbd4d68d2464736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/ERC721OnChain.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/ERC721OnChain.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/ERC721OnChain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/ERC721OnChain.json b/predeployed/build/lib/ima_predeployed/artifacts/ERC721OnChain.json new file mode 100644 index 000000000..293d82b2b --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/ERC721OnChain.json @@ -0,0 +1,722 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ERC721OnChain", + "sourceName": "contracts/schain/tokens/ERC721OnChain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "contractName", + "type": "string" + }, + { + "internalType": "string", + "name": "contractSymbol", + "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": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "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": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "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": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "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": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "tokenUri", + "type": "string" + } + ], + "name": "setTokenURI", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "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" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b506040516200344538038062003445833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604052505050620001b46200022760201b620012c81760201c565b620001cb8282620002e560201b620013791760201c565b620001e0620003b160201b620014361760201c565b620001fb600080516020620034258339815191528062000459565b6200021f6000805160206200342583398151915262000219620004ab565b620004af565b50506200094a565b600054610100900460ff168062000243575062000243620004bf565b8062000252575060005460ff16155b6200028f5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620002bb576000805460ff1961ff0019909116610100171660011790555b620002c5620004dd565b620002cf620004dd565b8015620002e2576000805461ff00191690555b50565b600054610100900460ff168062000301575062000301620004bf565b8062000310575060005460ff16155b6200034d5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000379576000805460ff1961ff0019909116610100171660011790555b62000383620004dd565b6200038d62000585565b6200039983836200062b565b8015620003ac576000805461ff00191690555b505050565b600054610100900460ff1680620003cd5750620003cd620004bf565b80620003dc575060005460ff16155b620004195760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000445576000805460ff1961ff0019909116610100171660011790555b6200044f620004dd565b620002c562000585565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620004bb828262000721565b5050565b6000620004d7306200079c60201b620014d31760201c565b15905090565b600054610100900460ff1680620004f95750620004f9620004bf565b8062000508575060005460ff16155b620005455760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620002cf576000805460ff1961ff0019909116610100171660011790558015620002e2576000805461ff001916905550565b600054610100900460ff1680620005a15750620005a1620004bf565b80620005b0575060005460ff16155b620005ed5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000619576000805460ff1961ff0019909116610100171660011790555b620002cf6301ffc9a760e01b620007a2565b600054610100900460ff168062000647575062000647620004bf565b8062000656575060005460ff16155b620006935760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620006bf576000805460ff1961ff0019909116610100171660011790555b8251620006d490609c906020860190620008ae565b508151620006ea90609d906020850190620008ae565b50620006fd6380ac58cd60e01b620007a2565b6200070f635b5e139f60e01b620007a2565b6200039963780e9d6360e01b620007a2565b600082815260336020908152604090912062000748918390620014d962000827821b17901c565b15620004bb5762000758620004ab565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b6001600160e01b0319808216141562000802576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b60006200083e836001600160a01b03841662000847565b90505b92915050565b600062000855838362000896565b6200088d5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000841565b50600062000841565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620008f157805160ff191683800117855562000921565b8280016001018555821562000921579182015b828111156200092157825182559160200191906001019062000904565b506200092f92915062000933565b5090565b5b808211156200092f576000815560010162000934565b612a9d806200095a6000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80634f6ccce711610104578063a217fddf116100a2578063ca15c87311610071578063ca15c873146106b2578063d5391393146106cf578063d547741f146106d7578063e985e9c514610703576101cf565b8063a217fddf14610599578063a22cb465146105a1578063b88d4fde146105cf578063c87b56dd14610695576101cf565b806370a08231116100de57806370a082311461051c5780639010d07c1461054257806391d148541461056557806395d89b4114610591576101cf565b80634f6ccce7146104da5780636352211e146104f75780636c0360eb14610514576101cf565b8063248a9ca31161017157806336568abe1161014b57806336568abe1461042f57806340c10f191461045b57806342842e0e1461048757806342966c68146104bd576101cf565b8063248a9ca3146103ba5780632f2ff15d146103d75780632f745c5914610403576101cf565b8063095ea7b3116101ad578063095ea7b3146102c5578063162094c4146102f357806318160ddd1461036a57806323b872dd14610384576101cf565b806301ffc9a7146101d457806306fdde031461020f578063081812fc1461028c575b600080fd5b6101fb600480360360208110156101ea57600080fd5b50356001600160e01b031916610731565b604080519115158252519081900360200190f35b610217610754565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610251578181015183820152602001610239565b50505050905090810190601f16801561027e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102a9600480360360208110156102a257600080fd5b50356107ea565b604080516001600160a01b039092168252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b506001600160a01b03813516906020013561084c565b005b6101fb6004803603604081101561030957600080fd5b8135919081019060408101602082013564010000000081111561032b57600080fd5b82018360208201111561033d57600080fd5b8035906020019184600183028401116401000000008311171561035f57600080fd5b509092509050610927565b610372610a21565b60408051918252519081900360200190f35b6102f16004803603606081101561039a57600080fd5b506001600160a01b03813581169160208101359091169060400135610a32565b610372600480360360208110156103d057600080fd5b5035610a89565b6102f1600480360360408110156103ed57600080fd5b50803590602001356001600160a01b0316610a9e565b6103726004803603604081101561041957600080fd5b506001600160a01b038135169060200135610b0a565b6102f16004803603604081101561044557600080fd5b50803590602001356001600160a01b0316610b35565b6102f16004803603604081101561047157600080fd5b506001600160a01b038135169060200135610b96565b6102f16004803603606081101561049d57600080fd5b506001600160a01b03813581169160208101359091169060400135610c16565b6102f1600480360360208110156104d357600080fd5b5035610c31565b610372600480360360208110156104f057600080fd5b5035610c83565b6102a96004803603602081101561050d57600080fd5b5035610c99565b610217610cc1565b6103726004803603602081101561053257600080fd5b50356001600160a01b0316610d22565b6102a96004803603604081101561055857600080fd5b5080359060200135610d8a565b6101fb6004803603604081101561057b57600080fd5b50803590602001356001600160a01b0316610da2565b610217610dba565b610372610e1b565b6102f1600480360360408110156105b757600080fd5b506001600160a01b0381351690602001351515610e20565b6102f1600480360360808110156105e557600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561062057600080fd5b82018360208201111561063257600080fd5b8035906020019184600183028401116401000000008311171561065457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f25945050505050565b610217600480360360208110156106ab57600080fd5b5035610f83565b610372600480360360208110156106c857600080fd5b5035611206565b61037261121d565b6102f1600480360360408110156106ed57600080fd5b50803590602001356001600160a01b0316611241565b6101fb6004803603604081101561071957600080fd5b506001600160a01b038135811691602001351661129a565b6001600160e01b0319811660009081526065602052604090205460ff165b919050565b609c8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b820191906000526020600020905b8154815290600101906020018083116107c357829003601f168201915b5050505050905090565b60006107f5826114ee565b6108305760405162461bcd60e51b815260040180806020018281038252602c815260200180612907602c913960400191505060405180910390fd5b506000908152609a60205260409020546001600160a01b031690565b600061085782610c99565b9050806001600160a01b0316836001600160a01b031614156108aa5760405162461bcd60e51b81526004018080602001828103825260218152602001806129b76021913960400191505060405180910390fd5b806001600160a01b03166108bc6114fb565b6001600160a01b031614806108dd57506108dd816108d86114fb565b61129a565b6109185760405162461bcd60e51b815260040180806020018281038252603881526020018061282c6038913960400191505060405180910390fd5b61092283836114ff565b505050565b6000610932846114ee565b61097b576040805162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b604482015290519081900360640190fd5b610985338561156d565b6109d6576040805162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e2055524900000000604482015290519081900360640190fd5b610a168484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161192505050565b5060015b9392505050565b6000610a2d6098611674565b905090565b610a43610a3d6114fb565b8261156d565b610a7e5760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b61092283838361167f565b60009081526033602052604090206002015490565b600082815260336020526040902060020154610ac190610abc6114fb565b610da2565b610afc5760405162461bcd60e51b815260040180806020018281038252602f81526020018061274b602f913960400191505060405180910390fd5b610b0682826117cb565b5050565b6001600160a01b0382166000908152609760205260408120610b2c9083611834565b90505b92915050565b610b3d6114fb565b6001600160a01b0316816001600160a01b031614610b8c5760405162461bcd60e51b815260040180806020018281038252602f815260200180612a39602f913960400191505060405180910390fd5b610b068282611840565b610bc27f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610abc6114fb565b610c0c576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610b0682826118a9565b61092283838360405180602001604052806000815250610f25565b610c3c610a3d6114fb565b610c775760405162461bcd60e51b8152600401808060200182810382526030815260200180612a096030913960400191505060405180910390fd5b610c80816119d7565b50565b600080610c91609884611aa4565b509392505050565b6000610b2f8260405180606001604052806029815260200161288e6029913960989190611ac0565b609f8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b60006001600160a01b038216610d695760405162461bcd60e51b815260040180806020018281038252602a815260200180612864602a913960400191505060405180910390fd5b6001600160a01b0382166000908152609760205260409020610b2f90611674565b6000828152603360205260408120610b2c9083611834565b6000828152603360205260408120610b2c9083611acd565b609d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b600081565b610e286114fb565b6001600160a01b0316826001600160a01b03161415610e8e576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80609b6000610e9b6114fb565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610edf6114fb565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610f36610f306114fb565b8361156d565b610f715760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b610f7d84848484611ae2565b50505050565b6060610f8e826114ee565b610fc95760405162461bcd60e51b815260040180806020018281038252602f815260200180612988602f913960400191505060405180910390fd5b6000828152609e602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561105e5780601f106110335761010080835404028352916020019161105e565b820191906000526020600020905b81548152906001019060200180831161104157829003601f168201915b50505050509050606061106f610cc1565b90508051600014156110835750905061074f565b8151156111445780826040516020018083805190602001908083835b602083106110be5780518252601f19909201916020918201910161109f565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111065780518252601f1990920191602091820191016110e7565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061074f565b8061114e85611b34565b6040516020018083805190602001908083835b602083106111805780518252601f199092019160209182019101611161565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111c85780518252601f1990920191602091820191016111a9565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b6000818152603360205260408120610b2f90611674565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b60008281526033602052604090206002015461125f90610abc6114fb565b610b8c5760405162461bcd60e51b81526004018080602001828103825260308152602001806127fc6030913960400191505060405180910390fd5b6001600160a01b039182166000908152609b6020908152604080832093909416825291909152205460ff1690565b600054610100900460ff16806112e157506112e1611c0f565b806112ef575060005460ff16155b61132a5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611355576000805460ff1961ff0019909116610100171660011790555b61135d611c20565b611365611c20565b8015610c80576000805461ff001916905550565b600054610100900460ff16806113925750611392611c0f565b806113a0575060005460ff16155b6113db5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611406576000805460ff1961ff0019909116610100171660011790555b61140e611c20565b611416611cc0565b6114208383611d5d565b8015610922576000805461ff0019169055505050565b600054610100900460ff168061144f575061144f611c0f565b8061145d575060005460ff16155b6114985760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff161580156114c3576000805460ff1961ff0019909116610100171660011790555b6114cb611c20565b61135d611cc0565b3b151590565b6000610b2c836001600160a01b038416611e42565b6000610b2f609883611e8c565b3390565b6000818152609a6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061153482610c99565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611578826114ee565b6115b35760405162461bcd60e51b815260040180806020018281038252602c8152602001806127d0602c913960400191505060405180910390fd5b60006115be83610c99565b9050806001600160a01b0316846001600160a01b031614806115f95750836001600160a01b03166115ee846107ea565b6001600160a01b0316145b806116095750611609818561129a565b949350505050565b61161a826114ee565b6116555760405162461bcd60e51b815260040180806020018281038252602c815260200180612933602c913960400191505060405180910390fd5b6000828152609e60209081526040909120825161092292840190612655565b6000610b2f82611e98565b826001600160a01b031661169282610c99565b6001600160a01b0316146116d75760405162461bcd60e51b815260040180806020018281038252602981526020018061295f6029913960400191505060405180910390fd5b6001600160a01b03821661171c5760405162461bcd60e51b81526004018080602001828103825260248152602001806127ac6024913960400191505060405180910390fd5b611727838383610922565b6117326000826114ff565b6001600160a01b03831660009081526097602052604090206117549082611e9c565b506001600160a01b03821660009081526097602052604090206117779082611ea8565b5061178460988284611eb4565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526033602052604090206117e390826114d9565b15610b06576117f06114fb565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610b2c8383611eca565b60008281526033602052604090206118589082611f2e565b15610b06576118656114fb565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038216611904576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61190d816114ee565b1561195f576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b61196b60008383610922565b6001600160a01b038216600090815260976020526040902061198d9082611ea8565b5061199a60988284611eb4565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006119e282610c99565b90506119f081600084610922565b6119fb6000836114ff565b6000828152609e60205260409020546002600019610100600184161502019091160415611a39576000828152609e60205260408120611a39916126d3565b6001600160a01b0381166000908152609760205260409020611a5b9083611e9c565b50611a67609883611f43565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000808080611ab38686611f4f565b9097909650945050505050565b6000611609848484611fca565b6000610b2c836001600160a01b038416612094565b611aed84848461167f565b611af9848484846120ac565b610f7d5760405162461bcd60e51b815260040180806020018281038252603281526020018061277a6032913960400191505060405180910390fd5b606081611b5957506040805180820190915260018152600360fc1b602082015261074f565b8160005b8115611b7157600101600a82049150611b5d565b60608167ffffffffffffffff81118015611b8a57600080fd5b506040519080825280601f01601f191660200182016040528015611bb5576020820181803683370190505b50859350905060001982015b8315611c0657600a840660300160f81b82828060019003935081518110611be457fe5b60200101906001600160f81b031916908160001a905350600a84049350611bc1565b50949350505050565b6000611c1a306114d3565b15905090565b600054610100900460ff1680611c395750611c39611c0f565b80611c47575060005460ff16155b611c825760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611365576000805460ff1961ff0019909116610100171660011790558015610c80576000805461ff001916905550565b600054610100900460ff1680611cd95750611cd9611c0f565b80611ce7575060005460ff16155b611d225760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611d4d576000805460ff1961ff0019909116610100171660011790555b6113656301ffc9a760e01b612214565b600054610100900460ff1680611d765750611d76611c0f565b80611d84575060005460ff16155b611dbf5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611dea576000805460ff1961ff0019909116610100171660011790555b8251611dfd90609c906020860190612655565b508151611e1190609d906020850190612655565b50611e226380ac58cd60e01b612214565b611e32635b5e139f60e01b612214565b61142063780e9d6360e01b612214565b6000611e4e8383612094565b611e8457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b2f565b506000610b2f565b6000610b2c8383612094565b5490565b6000610b2c8383612298565b6000610b2c8383611e42565b600061160984846001600160a01b03851661235e565b81546000908210611f0c5760405162461bcd60e51b81526004018080602001828103825260228152602001806127296022913960400191505060405180910390fd5b826000018281548110611f1b57fe5b9060005260206000200154905092915050565b6000610b2c836001600160a01b038416612298565b6000610b2c83836123f5565b815460009081908310611f935760405162461bcd60e51b81526004018080602001828103825260228152602001806128e56022913960400191505060405180910390fd5b6000846000018481548110611fa457fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816120655760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561202a578181015183820152602001612012565b50505050905090810190601f1680156120575780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061207857fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b60006120c0846001600160a01b03166114d3565b6120cc57506001611609565b60606121da630a85bd0160e11b6120e16114fb565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612148578181015183820152602001612130565b50505050905090810190601f1680156121755780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161277a603291396001600160a01b03881691906124c9565b905060008180602001905160208110156121f357600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160e01b03198082161415612273576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b6000818152600183016020526040812054801561235457835460001980830191908101906000908790839081106122cb57fe5b90600052602060002001549050808760000184815481106122e857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061231857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b2f565b6000915050610b2f565b6000828152600184016020526040812054806123c3575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055610a1a565b828560000160018303815481106123d657fe5b9060005260206000209060020201600101819055506000915050610a1a565b60008181526001830160205260408120548015612354578354600019808301919081019060009087908390811061242857fe5b906000526020600020906002020190508087600001848154811061244857fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061248757fe5b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610b2f9350505050565b60606116098484600085856124dd856114d3565b61252e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061256d5780518252601f19909201916020918201910161254e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146125cf576040519150601f19603f3d011682016040523d82523d6000602084013e6125d4565b606091505b50915091506125e48282866125ef565b979650505050505050565b606083156125fe575081610a1a565b82511561260e5782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561202a578181015183820152602001612012565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061269657805160ff19168380011785556126c3565b828001600101855582156126c3579182015b828111156126c35782518255916020019190600101906126a8565b506126cf929150612713565b5090565b50805460018160011615610100020316600290046000825580601f106126f95750610c80565b601f016020900490600052602060002090810190610c8091905b5b808211156126cf576000815560010161271456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212206cfed4af0d06c86fc24af2eff048829ddbcce69495200e80936dbbfb68bcbc3964736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c80634f6ccce711610104578063a217fddf116100a2578063ca15c87311610071578063ca15c873146106b2578063d5391393146106cf578063d547741f146106d7578063e985e9c514610703576101cf565b8063a217fddf14610599578063a22cb465146105a1578063b88d4fde146105cf578063c87b56dd14610695576101cf565b806370a08231116100de57806370a082311461051c5780639010d07c1461054257806391d148541461056557806395d89b4114610591576101cf565b80634f6ccce7146104da5780636352211e146104f75780636c0360eb14610514576101cf565b8063248a9ca31161017157806336568abe1161014b57806336568abe1461042f57806340c10f191461045b57806342842e0e1461048757806342966c68146104bd576101cf565b8063248a9ca3146103ba5780632f2ff15d146103d75780632f745c5914610403576101cf565b8063095ea7b3116101ad578063095ea7b3146102c5578063162094c4146102f357806318160ddd1461036a57806323b872dd14610384576101cf565b806301ffc9a7146101d457806306fdde031461020f578063081812fc1461028c575b600080fd5b6101fb600480360360208110156101ea57600080fd5b50356001600160e01b031916610731565b604080519115158252519081900360200190f35b610217610754565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610251578181015183820152602001610239565b50505050905090810190601f16801561027e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102a9600480360360208110156102a257600080fd5b50356107ea565b604080516001600160a01b039092168252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b506001600160a01b03813516906020013561084c565b005b6101fb6004803603604081101561030957600080fd5b8135919081019060408101602082013564010000000081111561032b57600080fd5b82018360208201111561033d57600080fd5b8035906020019184600183028401116401000000008311171561035f57600080fd5b509092509050610927565b610372610a21565b60408051918252519081900360200190f35b6102f16004803603606081101561039a57600080fd5b506001600160a01b03813581169160208101359091169060400135610a32565b610372600480360360208110156103d057600080fd5b5035610a89565b6102f1600480360360408110156103ed57600080fd5b50803590602001356001600160a01b0316610a9e565b6103726004803603604081101561041957600080fd5b506001600160a01b038135169060200135610b0a565b6102f16004803603604081101561044557600080fd5b50803590602001356001600160a01b0316610b35565b6102f16004803603604081101561047157600080fd5b506001600160a01b038135169060200135610b96565b6102f16004803603606081101561049d57600080fd5b506001600160a01b03813581169160208101359091169060400135610c16565b6102f1600480360360208110156104d357600080fd5b5035610c31565b610372600480360360208110156104f057600080fd5b5035610c83565b6102a96004803603602081101561050d57600080fd5b5035610c99565b610217610cc1565b6103726004803603602081101561053257600080fd5b50356001600160a01b0316610d22565b6102a96004803603604081101561055857600080fd5b5080359060200135610d8a565b6101fb6004803603604081101561057b57600080fd5b50803590602001356001600160a01b0316610da2565b610217610dba565b610372610e1b565b6102f1600480360360408110156105b757600080fd5b506001600160a01b0381351690602001351515610e20565b6102f1600480360360808110156105e557600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561062057600080fd5b82018360208201111561063257600080fd5b8035906020019184600183028401116401000000008311171561065457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f25945050505050565b610217600480360360208110156106ab57600080fd5b5035610f83565b610372600480360360208110156106c857600080fd5b5035611206565b61037261121d565b6102f1600480360360408110156106ed57600080fd5b50803590602001356001600160a01b0316611241565b6101fb6004803603604081101561071957600080fd5b506001600160a01b038135811691602001351661129a565b6001600160e01b0319811660009081526065602052604090205460ff165b919050565b609c8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b820191906000526020600020905b8154815290600101906020018083116107c357829003601f168201915b5050505050905090565b60006107f5826114ee565b6108305760405162461bcd60e51b815260040180806020018281038252602c815260200180612907602c913960400191505060405180910390fd5b506000908152609a60205260409020546001600160a01b031690565b600061085782610c99565b9050806001600160a01b0316836001600160a01b031614156108aa5760405162461bcd60e51b81526004018080602001828103825260218152602001806129b76021913960400191505060405180910390fd5b806001600160a01b03166108bc6114fb565b6001600160a01b031614806108dd57506108dd816108d86114fb565b61129a565b6109185760405162461bcd60e51b815260040180806020018281038252603881526020018061282c6038913960400191505060405180910390fd5b61092283836114ff565b505050565b6000610932846114ee565b61097b576040805162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b604482015290519081900360640190fd5b610985338561156d565b6109d6576040805162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e2055524900000000604482015290519081900360640190fd5b610a168484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161192505050565b5060015b9392505050565b6000610a2d6098611674565b905090565b610a43610a3d6114fb565b8261156d565b610a7e5760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b61092283838361167f565b60009081526033602052604090206002015490565b600082815260336020526040902060020154610ac190610abc6114fb565b610da2565b610afc5760405162461bcd60e51b815260040180806020018281038252602f81526020018061274b602f913960400191505060405180910390fd5b610b0682826117cb565b5050565b6001600160a01b0382166000908152609760205260408120610b2c9083611834565b90505b92915050565b610b3d6114fb565b6001600160a01b0316816001600160a01b031614610b8c5760405162461bcd60e51b815260040180806020018281038252602f815260200180612a39602f913960400191505060405180910390fd5b610b068282611840565b610bc27f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610abc6114fb565b610c0c576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610b0682826118a9565b61092283838360405180602001604052806000815250610f25565b610c3c610a3d6114fb565b610c775760405162461bcd60e51b8152600401808060200182810382526030815260200180612a096030913960400191505060405180910390fd5b610c80816119d7565b50565b600080610c91609884611aa4565b509392505050565b6000610b2f8260405180606001604052806029815260200161288e6029913960989190611ac0565b609f8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b60006001600160a01b038216610d695760405162461bcd60e51b815260040180806020018281038252602a815260200180612864602a913960400191505060405180910390fd5b6001600160a01b0382166000908152609760205260409020610b2f90611674565b6000828152603360205260408120610b2c9083611834565b6000828152603360205260408120610b2c9083611acd565b609d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b600081565b610e286114fb565b6001600160a01b0316826001600160a01b03161415610e8e576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80609b6000610e9b6114fb565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610edf6114fb565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610f36610f306114fb565b8361156d565b610f715760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b610f7d84848484611ae2565b50505050565b6060610f8e826114ee565b610fc95760405162461bcd60e51b815260040180806020018281038252602f815260200180612988602f913960400191505060405180910390fd5b6000828152609e602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561105e5780601f106110335761010080835404028352916020019161105e565b820191906000526020600020905b81548152906001019060200180831161104157829003601f168201915b50505050509050606061106f610cc1565b90508051600014156110835750905061074f565b8151156111445780826040516020018083805190602001908083835b602083106110be5780518252601f19909201916020918201910161109f565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111065780518252601f1990920191602091820191016110e7565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061074f565b8061114e85611b34565b6040516020018083805190602001908083835b602083106111805780518252601f199092019160209182019101611161565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111c85780518252601f1990920191602091820191016111a9565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b6000818152603360205260408120610b2f90611674565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b60008281526033602052604090206002015461125f90610abc6114fb565b610b8c5760405162461bcd60e51b81526004018080602001828103825260308152602001806127fc6030913960400191505060405180910390fd5b6001600160a01b039182166000908152609b6020908152604080832093909416825291909152205460ff1690565b600054610100900460ff16806112e157506112e1611c0f565b806112ef575060005460ff16155b61132a5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611355576000805460ff1961ff0019909116610100171660011790555b61135d611c20565b611365611c20565b8015610c80576000805461ff001916905550565b600054610100900460ff16806113925750611392611c0f565b806113a0575060005460ff16155b6113db5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611406576000805460ff1961ff0019909116610100171660011790555b61140e611c20565b611416611cc0565b6114208383611d5d565b8015610922576000805461ff0019169055505050565b600054610100900460ff168061144f575061144f611c0f565b8061145d575060005460ff16155b6114985760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff161580156114c3576000805460ff1961ff0019909116610100171660011790555b6114cb611c20565b61135d611cc0565b3b151590565b6000610b2c836001600160a01b038416611e42565b6000610b2f609883611e8c565b3390565b6000818152609a6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061153482610c99565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611578826114ee565b6115b35760405162461bcd60e51b815260040180806020018281038252602c8152602001806127d0602c913960400191505060405180910390fd5b60006115be83610c99565b9050806001600160a01b0316846001600160a01b031614806115f95750836001600160a01b03166115ee846107ea565b6001600160a01b0316145b806116095750611609818561129a565b949350505050565b61161a826114ee565b6116555760405162461bcd60e51b815260040180806020018281038252602c815260200180612933602c913960400191505060405180910390fd5b6000828152609e60209081526040909120825161092292840190612655565b6000610b2f82611e98565b826001600160a01b031661169282610c99565b6001600160a01b0316146116d75760405162461bcd60e51b815260040180806020018281038252602981526020018061295f6029913960400191505060405180910390fd5b6001600160a01b03821661171c5760405162461bcd60e51b81526004018080602001828103825260248152602001806127ac6024913960400191505060405180910390fd5b611727838383610922565b6117326000826114ff565b6001600160a01b03831660009081526097602052604090206117549082611e9c565b506001600160a01b03821660009081526097602052604090206117779082611ea8565b5061178460988284611eb4565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526033602052604090206117e390826114d9565b15610b06576117f06114fb565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610b2c8383611eca565b60008281526033602052604090206118589082611f2e565b15610b06576118656114fb565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038216611904576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61190d816114ee565b1561195f576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b61196b60008383610922565b6001600160a01b038216600090815260976020526040902061198d9082611ea8565b5061199a60988284611eb4565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006119e282610c99565b90506119f081600084610922565b6119fb6000836114ff565b6000828152609e60205260409020546002600019610100600184161502019091160415611a39576000828152609e60205260408120611a39916126d3565b6001600160a01b0381166000908152609760205260409020611a5b9083611e9c565b50611a67609883611f43565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000808080611ab38686611f4f565b9097909650945050505050565b6000611609848484611fca565b6000610b2c836001600160a01b038416612094565b611aed84848461167f565b611af9848484846120ac565b610f7d5760405162461bcd60e51b815260040180806020018281038252603281526020018061277a6032913960400191505060405180910390fd5b606081611b5957506040805180820190915260018152600360fc1b602082015261074f565b8160005b8115611b7157600101600a82049150611b5d565b60608167ffffffffffffffff81118015611b8a57600080fd5b506040519080825280601f01601f191660200182016040528015611bb5576020820181803683370190505b50859350905060001982015b8315611c0657600a840660300160f81b82828060019003935081518110611be457fe5b60200101906001600160f81b031916908160001a905350600a84049350611bc1565b50949350505050565b6000611c1a306114d3565b15905090565b600054610100900460ff1680611c395750611c39611c0f565b80611c47575060005460ff16155b611c825760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611365576000805460ff1961ff0019909116610100171660011790558015610c80576000805461ff001916905550565b600054610100900460ff1680611cd95750611cd9611c0f565b80611ce7575060005460ff16155b611d225760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611d4d576000805460ff1961ff0019909116610100171660011790555b6113656301ffc9a760e01b612214565b600054610100900460ff1680611d765750611d76611c0f565b80611d84575060005460ff16155b611dbf5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611dea576000805460ff1961ff0019909116610100171660011790555b8251611dfd90609c906020860190612655565b508151611e1190609d906020850190612655565b50611e226380ac58cd60e01b612214565b611e32635b5e139f60e01b612214565b61142063780e9d6360e01b612214565b6000611e4e8383612094565b611e8457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b2f565b506000610b2f565b6000610b2c8383612094565b5490565b6000610b2c8383612298565b6000610b2c8383611e42565b600061160984846001600160a01b03851661235e565b81546000908210611f0c5760405162461bcd60e51b81526004018080602001828103825260228152602001806127296022913960400191505060405180910390fd5b826000018281548110611f1b57fe5b9060005260206000200154905092915050565b6000610b2c836001600160a01b038416612298565b6000610b2c83836123f5565b815460009081908310611f935760405162461bcd60e51b81526004018080602001828103825260228152602001806128e56022913960400191505060405180910390fd5b6000846000018481548110611fa457fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816120655760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561202a578181015183820152602001612012565b50505050905090810190601f1680156120575780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061207857fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b60006120c0846001600160a01b03166114d3565b6120cc57506001611609565b60606121da630a85bd0160e11b6120e16114fb565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612148578181015183820152602001612130565b50505050905090810190601f1680156121755780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161277a603291396001600160a01b03881691906124c9565b905060008180602001905160208110156121f357600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160e01b03198082161415612273576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b6000818152600183016020526040812054801561235457835460001980830191908101906000908790839081106122cb57fe5b90600052602060002001549050808760000184815481106122e857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061231857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b2f565b6000915050610b2f565b6000828152600184016020526040812054806123c3575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055610a1a565b828560000160018303815481106123d657fe5b9060005260206000209060020201600101819055506000915050610a1a565b60008181526001830160205260408120548015612354578354600019808301919081019060009087908390811061242857fe5b906000526020600020906002020190508087600001848154811061244857fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061248757fe5b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610b2f9350505050565b60606116098484600085856124dd856114d3565b61252e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061256d5780518252601f19909201916020918201910161254e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146125cf576040519150601f19603f3d011682016040523d82523d6000602084013e6125d4565b606091505b50915091506125e48282866125ef565b979650505050505050565b606083156125fe575081610a1a565b82511561260e5782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561202a578181015183820152602001612012565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061269657805160ff19168380011785556126c3565b828001600101855582156126c3579182015b828111156126c35782518255916020019190600101906126a8565b506126cf929150612713565b5090565b50805460018160011615610100020316600290046000825580601f106126f95750610c80565b601f016020900490600052602060002090810190610c8091905b5b808211156126cf576000815560010161271456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212206cfed4af0d06c86fc24af2eff048829ddbcce69495200e80936dbbfb68bcbc3964736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/EthErc20.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/EthErc20.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/EthErc20.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/EthErc20.json b/predeployed/build/lib/ima_predeployed/artifacts/EthErc20.json new file mode 100644 index 000000000..6d5862dc6 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/EthErc20.json @@ -0,0 +1,615 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "EthErc20", + "sourceName": "contracts/schain/tokens/EthErc20.sol", + "abi": [ + { + "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": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "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": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "forceBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": "address", + "name": "tokenManagerEthAddress", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "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": "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" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50611b5a806100206000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c806379cc6790116100de578063a9059cbb11610097578063d539139311610071578063d53913931461051a578063d547741f14610522578063dd62ed3e1461054e578063e2d6f6341461057c5761018e565b8063a9059cbb146104ab578063c4d66de8146104d7578063ca15c873146104fd5761018e565b806379cc6790146103d85780639010d07c1461040457806391d148541461044357806395d89b411461046f578063a217fddf14610477578063a457c2d71461047f5761018e565b80632f2ff15d1161014b5780633950935111610125578063395093511461033d57806340c10f191461036957806342966c681461039557806370a08231146103b25761018e565b80632f2ff15d146102c5578063313ce567146102f357806336568abe146103115761018e565b806306fdde0314610193578063095ea7b31461021057806318160ddd1461025057806323b872dd1461026a578063248a9ca3146102a0578063282c51f3146102bd575b600080fd5b61019b6105a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101d55781810151838201526020016101bd565b50505050905090810190601f1680156102025780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61023c6004803603604081101561022657600080fd5b506001600160a01b03813516906020013561063e565b604080519115158252519081900360200190f35b61025861065c565b60408051918252519081900360200190f35b61023c6004803603606081101561028057600080fd5b506001600160a01b03813581169160208101359091169060400135610662565b610258600480360360208110156102b657600080fd5b50356106e9565b6102586106fe565b6102f1600480360360408110156102db57600080fd5b50803590602001356001600160a01b0316610722565b005b6102fb61078e565b6040805160ff9092168252519081900360200190f35b6102f16004803603604081101561032757600080fd5b50803590602001356001600160a01b0316610797565b61023c6004803603604081101561035357600080fd5b506001600160a01b0381351690602001356107f8565b6102f16004803603604081101561037f57600080fd5b506001600160a01b038135169060200135610846565b6102f1600480360360208110156103ab57600080fd5b50356108cd565b610258600480360360208110156103c857600080fd5b50356001600160a01b03166108e1565b6102f1600480360360408110156103ee57600080fd5b506001600160a01b0381351690602001356108fc565b6104276004803603604081101561041a57600080fd5b5080359060200135610956565b604080516001600160a01b039092168252519081900360200190f35b61023c6004803603604081101561045957600080fd5b50803590602001356001600160a01b0316610975565b61019b61098d565b6102586109ee565b61023c6004803603604081101561049557600080fd5b506001600160a01b0381351690602001356109f3565b61023c600480360360408110156104c157600080fd5b506001600160a01b038135169060200135610a5b565b6102f1600480360360208110156104ed57600080fd5b50356001600160a01b0316610a6f565b6102586004803603602081101561051357600080fd5b5035610bcf565b610258610be6565b6102f16004803603604081101561053857600080fd5b50803590602001356001600160a01b0316610c0a565b6102586004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610c63565b6102f16004803603604081101561059257600080fd5b506001600160a01b038135169060200135610c8e565b60688054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106345780601f1061060957610100808354040283529160200191610634565b820191906000526020600020905b81548152906001019060200180831161061757829003601f168201915b5050505050905090565b600061065261064b610d15565b8484610d19565b5060015b92915050565b60675490565b600061066f848484610e05565b6106df8461067b610d15565b6106da85604051806060016040528060288152602001611a1b602891396001600160a01b038a166000908152606660205260408120906106b9610d15565b6001600160a01b031681526020810191909152604001600020549190610f62565b610d19565b5060019392505050565b60009081526033602052604090206002015490565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b60008281526033602052604090206002015461074590610740610d15565b610975565b6107805760405162461bcd60e51b815260040180806020018281038252602f815260200180611924602f913960400191505060405180910390fd5b61078a8282610ff9565b5050565b606a5460ff1690565b61079f610d15565b6001600160a01b0316816001600160a01b0316146107ee5760405162461bcd60e51b815260040180806020018281038252602f815260200180611af6602f913960400191505060405180910390fd5b61078a8282611062565b6000610652610805610d15565b846106da8560666000610816610d15565b6001600160a01b03908116825260208083019390935260409182016000908120918c1681529252902054906110cb565b6108727f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610740610d15565b6108c3576040805162461bcd60e51b815260206004820152601760248201527f4d494e54455220726f6c65206973207265717569726564000000000000000000604482015290519081900360640190fd5b61078a8282611125565b6108de6108d8610d15565b82611217565b50565b6001600160a01b031660009081526065602052604090205490565b600061093382604051806060016040528060248152602001611a436024913961092c86610927610d15565b610c63565b9190610f62565b905061094783610941610d15565b83610d19565b6109518383611217565b505050565b600082815260336020526040812061096e9083611313565b9392505050565b600082815260336020526040812061096e908361131f565b60698054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106345780601f1061060957610100808354040283529160200191610634565b600081565b6000610652610a00610d15565b846106da85604051806060016040528060258152602001611ad16025913960666000610a2a610d15565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610f62565b6000610652610a68610d15565b8484610e05565b600054610100900460ff1680610a885750610a88611334565b80610a96575060005460ff16155b610ad15760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff16158015610afc576000805460ff1961ff0019909116610100171660011790555b610b04611345565b610b5360405180604001604052806011815260200170455243323020457468657220436c6f6e6560781b815250604051806040016040528060048152602001634554484360e01b8152506113f6565b610b5b611345565b610b66600033610780565b610b907f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a683610780565b610bba7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84883610780565b801561078a576000805461ff00191690555050565b6000818152603360205260408120610656906114ab565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b600082815260336020526040902060020154610c2890610740610d15565b6107ee5760405162461bcd60e51b81526004018080602001828103825260308152602001806119bd6030913960400191505060405180910390fd5b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b610cba7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610740610d15565b610d0b576040805162461bcd60e51b815260206004820152601760248201527f4255524e455220726f6c65206973207265717569726564000000000000000000604482015290519081900360640190fd5b61078a8282611217565b3390565b6001600160a01b038316610d5e5760405162461bcd60e51b8152600401808060200182810382526024815260200180611aad6024913960400191505060405180910390fd5b6001600160a01b038216610da35760405162461bcd60e51b81526004018080602001828103825260228152602001806119756022913960400191505060405180910390fd5b6001600160a01b03808416600081815260666020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610e4a5760405162461bcd60e51b8152600401808060200182810382526025815260200180611a886025913960400191505060405180910390fd5b6001600160a01b038216610e8f5760405162461bcd60e51b81526004018080602001828103825260238152602001806119016023913960400191505060405180910390fd5b610e9a838383610951565b610ed781604051806060016040528060268152602001611997602691396001600160a01b0386166000908152606560205260409020549190610f62565b6001600160a01b038085166000908152606560205260408082209390935590841681522054610f0690826110cb565b6001600160a01b0380841660008181526065602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610ff15760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610fb6578181015183820152602001610f9e565b50505050905090810190601f168015610fe35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082815260336020526040902061101190826114b6565b1561078a5761101e610d15565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260336020526040902061107a90826114cb565b1561078a57611087610d15565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008282018381101561096e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216611180576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61118c60008383610951565b60675461119990826110cb565b6067556001600160a01b0382166000908152606560205260409020546111bf90826110cb565b6001600160a01b03831660008181526065602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b03821661125c5760405162461bcd60e51b8152600401808060200182810382526021815260200180611a676021913960400191505060405180910390fd5b61126882600083610951565b6112a581604051806060016040528060228152602001611953602291396001600160a01b0385166000908152606560205260409020549190610f62565b6001600160a01b0383166000908152606560205260409020556067546112cb90826114e0565b6067556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b600061096e838361153d565b600061096e836001600160a01b0384166115a1565b600061133f306115b9565b15905090565b600054610100900460ff168061135e575061135e611334565b8061136c575060005460ff16155b6113a75760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff161580156113d2576000805460ff1961ff0019909116610100171660011790555b6113da6115bf565b6113e26115bf565b80156108de576000805461ff001916905550565b600054610100900460ff168061140f575061140f611334565b8061141d575060005460ff16155b6114585760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff16158015611483576000805460ff1961ff0019909116610100171660011790555b61148b6115bf565b611495838361165f565b8015610951576000805461ff0019169055505050565b600061065682611737565b600061096e836001600160a01b03841661173b565b600061096e836001600160a01b038416611785565b600082821115611537576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b8154600090821061157f5760405162461bcd60e51b81526004018080602001828103825260228152602001806118df6022913960400191505060405180910390fd5b82600001828154811061158e57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b3b151590565b600054610100900460ff16806115d857506115d8611334565b806115e6575060005460ff16155b6116215760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff161580156113e2576000805460ff1961ff00199091166101001716600117905580156108de576000805461ff001916905550565b600054610100900460ff16806116785750611678611334565b80611686575060005460ff16155b6116c15760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff161580156116ec576000805460ff1961ff0019909116610100171660011790555b82516116ff90606890602086019061184b565b50815161171390606990602085019061184b565b50606a805460ff191660121790558015610951576000805461ff0019169055505050565b5490565b600061174783836115a1565b61177d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610656565b506000610656565b6000818152600183016020526040812054801561184157835460001980830191908101906000908790839081106117b857fe5b90600052602060002001549050808760000184815481106117d557fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061180557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610656565b6000915050610656565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061188c57805160ff19168380011785556118b9565b828001600101855582156118b9579182015b828111156118b957825182559160200191906001019061189e565b506118c59291506118c9565b5090565b5b808211156118c557600081556001016118ca56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7445524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212201356ff31fdcc22341ece4d4b5497010c80f00e126998f2573f67551e2649eda664736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c806379cc6790116100de578063a9059cbb11610097578063d539139311610071578063d53913931461051a578063d547741f14610522578063dd62ed3e1461054e578063e2d6f6341461057c5761018e565b8063a9059cbb146104ab578063c4d66de8146104d7578063ca15c873146104fd5761018e565b806379cc6790146103d85780639010d07c1461040457806391d148541461044357806395d89b411461046f578063a217fddf14610477578063a457c2d71461047f5761018e565b80632f2ff15d1161014b5780633950935111610125578063395093511461033d57806340c10f191461036957806342966c681461039557806370a08231146103b25761018e565b80632f2ff15d146102c5578063313ce567146102f357806336568abe146103115761018e565b806306fdde0314610193578063095ea7b31461021057806318160ddd1461025057806323b872dd1461026a578063248a9ca3146102a0578063282c51f3146102bd575b600080fd5b61019b6105a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101d55781810151838201526020016101bd565b50505050905090810190601f1680156102025780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61023c6004803603604081101561022657600080fd5b506001600160a01b03813516906020013561063e565b604080519115158252519081900360200190f35b61025861065c565b60408051918252519081900360200190f35b61023c6004803603606081101561028057600080fd5b506001600160a01b03813581169160208101359091169060400135610662565b610258600480360360208110156102b657600080fd5b50356106e9565b6102586106fe565b6102f1600480360360408110156102db57600080fd5b50803590602001356001600160a01b0316610722565b005b6102fb61078e565b6040805160ff9092168252519081900360200190f35b6102f16004803603604081101561032757600080fd5b50803590602001356001600160a01b0316610797565b61023c6004803603604081101561035357600080fd5b506001600160a01b0381351690602001356107f8565b6102f16004803603604081101561037f57600080fd5b506001600160a01b038135169060200135610846565b6102f1600480360360208110156103ab57600080fd5b50356108cd565b610258600480360360208110156103c857600080fd5b50356001600160a01b03166108e1565b6102f1600480360360408110156103ee57600080fd5b506001600160a01b0381351690602001356108fc565b6104276004803603604081101561041a57600080fd5b5080359060200135610956565b604080516001600160a01b039092168252519081900360200190f35b61023c6004803603604081101561045957600080fd5b50803590602001356001600160a01b0316610975565b61019b61098d565b6102586109ee565b61023c6004803603604081101561049557600080fd5b506001600160a01b0381351690602001356109f3565b61023c600480360360408110156104c157600080fd5b506001600160a01b038135169060200135610a5b565b6102f1600480360360208110156104ed57600080fd5b50356001600160a01b0316610a6f565b6102586004803603602081101561051357600080fd5b5035610bcf565b610258610be6565b6102f16004803603604081101561053857600080fd5b50803590602001356001600160a01b0316610c0a565b6102586004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610c63565b6102f16004803603604081101561059257600080fd5b506001600160a01b038135169060200135610c8e565b60688054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106345780601f1061060957610100808354040283529160200191610634565b820191906000526020600020905b81548152906001019060200180831161061757829003601f168201915b5050505050905090565b600061065261064b610d15565b8484610d19565b5060015b92915050565b60675490565b600061066f848484610e05565b6106df8461067b610d15565b6106da85604051806060016040528060288152602001611a1b602891396001600160a01b038a166000908152606660205260408120906106b9610d15565b6001600160a01b031681526020810191909152604001600020549190610f62565b610d19565b5060019392505050565b60009081526033602052604090206002015490565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b60008281526033602052604090206002015461074590610740610d15565b610975565b6107805760405162461bcd60e51b815260040180806020018281038252602f815260200180611924602f913960400191505060405180910390fd5b61078a8282610ff9565b5050565b606a5460ff1690565b61079f610d15565b6001600160a01b0316816001600160a01b0316146107ee5760405162461bcd60e51b815260040180806020018281038252602f815260200180611af6602f913960400191505060405180910390fd5b61078a8282611062565b6000610652610805610d15565b846106da8560666000610816610d15565b6001600160a01b03908116825260208083019390935260409182016000908120918c1681529252902054906110cb565b6108727f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610740610d15565b6108c3576040805162461bcd60e51b815260206004820152601760248201527f4d494e54455220726f6c65206973207265717569726564000000000000000000604482015290519081900360640190fd5b61078a8282611125565b6108de6108d8610d15565b82611217565b50565b6001600160a01b031660009081526065602052604090205490565b600061093382604051806060016040528060248152602001611a436024913961092c86610927610d15565b610c63565b9190610f62565b905061094783610941610d15565b83610d19565b6109518383611217565b505050565b600082815260336020526040812061096e9083611313565b9392505050565b600082815260336020526040812061096e908361131f565b60698054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106345780601f1061060957610100808354040283529160200191610634565b600081565b6000610652610a00610d15565b846106da85604051806060016040528060258152602001611ad16025913960666000610a2a610d15565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610f62565b6000610652610a68610d15565b8484610e05565b600054610100900460ff1680610a885750610a88611334565b80610a96575060005460ff16155b610ad15760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff16158015610afc576000805460ff1961ff0019909116610100171660011790555b610b04611345565b610b5360405180604001604052806011815260200170455243323020457468657220436c6f6e6560781b815250604051806040016040528060048152602001634554484360e01b8152506113f6565b610b5b611345565b610b66600033610780565b610b907f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a683610780565b610bba7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84883610780565b801561078a576000805461ff00191690555050565b6000818152603360205260408120610656906114ab565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b600082815260336020526040902060020154610c2890610740610d15565b6107ee5760405162461bcd60e51b81526004018080602001828103825260308152602001806119bd6030913960400191505060405180910390fd5b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b610cba7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610740610d15565b610d0b576040805162461bcd60e51b815260206004820152601760248201527f4255524e455220726f6c65206973207265717569726564000000000000000000604482015290519081900360640190fd5b61078a8282611217565b3390565b6001600160a01b038316610d5e5760405162461bcd60e51b8152600401808060200182810382526024815260200180611aad6024913960400191505060405180910390fd5b6001600160a01b038216610da35760405162461bcd60e51b81526004018080602001828103825260228152602001806119756022913960400191505060405180910390fd5b6001600160a01b03808416600081815260666020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610e4a5760405162461bcd60e51b8152600401808060200182810382526025815260200180611a886025913960400191505060405180910390fd5b6001600160a01b038216610e8f5760405162461bcd60e51b81526004018080602001828103825260238152602001806119016023913960400191505060405180910390fd5b610e9a838383610951565b610ed781604051806060016040528060268152602001611997602691396001600160a01b0386166000908152606560205260409020549190610f62565b6001600160a01b038085166000908152606560205260408082209390935590841681522054610f0690826110cb565b6001600160a01b0380841660008181526065602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610ff15760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610fb6578181015183820152602001610f9e565b50505050905090810190601f168015610fe35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082815260336020526040902061101190826114b6565b1561078a5761101e610d15565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260336020526040902061107a90826114cb565b1561078a57611087610d15565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008282018381101561096e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216611180576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61118c60008383610951565b60675461119990826110cb565b6067556001600160a01b0382166000908152606560205260409020546111bf90826110cb565b6001600160a01b03831660008181526065602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b03821661125c5760405162461bcd60e51b8152600401808060200182810382526021815260200180611a676021913960400191505060405180910390fd5b61126882600083610951565b6112a581604051806060016040528060228152602001611953602291396001600160a01b0385166000908152606560205260409020549190610f62565b6001600160a01b0383166000908152606560205260409020556067546112cb90826114e0565b6067556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b600061096e838361153d565b600061096e836001600160a01b0384166115a1565b600061133f306115b9565b15905090565b600054610100900460ff168061135e575061135e611334565b8061136c575060005460ff16155b6113a75760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff161580156113d2576000805460ff1961ff0019909116610100171660011790555b6113da6115bf565b6113e26115bf565b80156108de576000805461ff001916905550565b600054610100900460ff168061140f575061140f611334565b8061141d575060005460ff16155b6114585760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff16158015611483576000805460ff1961ff0019909116610100171660011790555b61148b6115bf565b611495838361165f565b8015610951576000805461ff0019169055505050565b600061065682611737565b600061096e836001600160a01b03841661173b565b600061096e836001600160a01b038416611785565b600082821115611537576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b8154600090821061157f5760405162461bcd60e51b81526004018080602001828103825260228152602001806118df6022913960400191505060405180910390fd5b82600001828154811061158e57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b3b151590565b600054610100900460ff16806115d857506115d8611334565b806115e6575060005460ff16155b6116215760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff161580156113e2576000805460ff1961ff00199091166101001716600117905580156108de576000805461ff001916905550565b600054610100900460ff16806116785750611678611334565b80611686575060005460ff16155b6116c15760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ed602e913960400191505060405180910390fd5b600054610100900460ff161580156116ec576000805460ff1961ff0019909116610100171660011790555b82516116ff90606890602086019061184b565b50815161171390606990602085019061184b565b50606a805460ff191660121790558015610951576000805461ff0019169055505050565b5490565b600061174783836115a1565b61177d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610656565b506000610656565b6000818152600183016020526040812054801561184157835460001980830191908101906000908790839081106117b857fe5b90600052602060002001549050808760000184815481106117d557fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061180557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610656565b6000915050610656565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061188c57805160ff19168380011785556118b9565b828001600101855582156118b9579182015b828111156118b957825182559160200191906001019061189e565b506118c59291506118c9565b5090565b5b808211156118c557600081556001016118ca56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7445524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212201356ff31fdcc22341ece4d4b5497010c80f00e126998f2573f67551e2649eda664736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/Fp2Operations.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/Fp2Operations.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/Fp2Operations.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/Fp2Operations.json b/predeployed/build/lib/ima_predeployed/artifacts/Fp2Operations.json new file mode 100644 index 000000000..2c3f6ab14 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/Fp2Operations.json @@ -0,0 +1,24 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "Fp2Operations", + "sourceName": "contracts/schain/bls/FieldOperations.sol", + "abi": [ + { + "inputs": [], + "name": "P", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60aa610024600b82828239805160001a607314601757fe5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c80638b8fbd92146038575b600080fd5b603e6050565b60408051918252519081900360200190f35b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478156fea264697066735822122005a640d392fc5f1ed84e8cfcb3f106269ba47e2bcf80fe41b37878441a2a89b964736f6c634300060c0033", + "deployedBytecode": "0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c80638b8fbd92146038575b600080fd5b603e6050565b60408051918252519081900360200190f35b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478156fea264697066735822122005a640d392fc5f1ed84e8cfcb3f106269ba47e2bcf80fe41b37878441a2a89b964736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/G1Operations.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/G1Operations.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/G1Operations.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/G1Operations.json b/predeployed/build/lib/ima_predeployed/artifacts/G1Operations.json new file mode 100644 index 000000000..c6c1a6b31 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/G1Operations.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "G1Operations", + "sourceName": "contracts/schain/bls/FieldOperations.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d2c7b848dbfe44c933cb9e4077309629271826944e59921445c8d65473cd143764736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d2c7b848dbfe44c933cb9e4077309629271826944e59921445c8d65473cd143764736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/G2Operations.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/G2Operations.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/G2Operations.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/G2Operations.json b/predeployed/build/lib/ima_predeployed/artifacts/G2Operations.json new file mode 100644 index 000000000..cd49226e3 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/G2Operations.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "G2Operations", + "sourceName": "contracts/schain/bls/FieldOperations.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122040e04307c36dd999e61c62d94b18263ca666c66ec90fcc123cb0d3e290e4fd3e64736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122040e04307c36dd999e61c62d94b18263ca666c66ec90fcc123cb0d3e290e4fd3e64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/IContractReceiverForSchain.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/IContractReceiverForSchain.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/IContractReceiverForSchain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/IContractReceiverForSchain.json b/predeployed/build/lib/ima_predeployed/artifacts/IContractReceiverForSchain.json new file mode 100644 index 000000000..3bea12cc7 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/IContractReceiverForSchain.json @@ -0,0 +1,40 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "IContractReceiverForSchain", + "sourceName": "contracts/schain/MessageProxyForSchain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/KeyStorage.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/KeyStorage.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/KeyStorage.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/KeyStorage.json b/predeployed/build/lib/ima_predeployed/artifacts/KeyStorage.json new file mode 100644 index 000000000..7c5e9fd45 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/KeyStorage.json @@ -0,0 +1,321 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "KeyStorage", + "sourceName": "contracts/schain/KeyStorage.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FN_NUM_GET_CONFIG_VARIABLE_UINT256", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FREE_MEM_PTR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlsCommonPublicKey", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "internalType": "struct Fp2Operations.Fp2Point", + "name": "x", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "internalType": "struct Fp2Operations.Fp2Point", + "name": "y", + "type": "tuple" + } + ], + "internalType": "struct G2Operations.G2Point", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610c37806100206000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80639010d07c116100715780639010d07c1461012f57806391d148541461014f578063a217fddf1461016f578063ab2a585314610177578063ca15c8731461017f578063d547741f14610192576100b4565b8063248a9ca3146100b95780632f2ff15d146100e257806336568abe146100f7578063554ef7a61461010a578063573c8aba1461011f5780638129fc1c14610127575b600080fd5b6100cc6100c73660046108ad565b6101a5565b6040516100d9919061094e565b60405180910390f35b6100f56100f03660046108c5565b6101ba565b005b6100f56101053660046108c5565b61020b565b61011261024d565b6040516100d99190610b0c565b6100cc61030c565b6100f5610311565b61014261013d3660046108ff565b6103a7565b6040516100d9919061092f565b61016261015d3660046108c5565b6103c8565b6040516100d99190610943565b6100cc6103e0565b6100cc6103e5565b6100cc61018d3660046108ad565b6103ea565b6100f56101a03660046108c5565b610401565b60009081526033602052604090206002015490565b6000828152603360205260409020600201546101d89061015d61043b565b6101fd5760405162461bcd60e51b81526004016101f490610999565b60405180910390fd5b610207828261043f565b5050565b61021361043b565b6001600160a01b0316816001600160a01b0316146102435760405162461bcd60e51b81526004016101f490610abd565b61020782826104a8565b61025561086e565b6040805160e0810182526034608082018181529192839290830191829161028391610b3260a0870139610511565b81526020016102a9604051806060016040528060348152602001610bce60349139610511565b815250815260200160405180604001604052806102dd604051806060016040528060348152602001610b9a60349139610511565b8152602001610303604051806060016040528060348152602001610b6660349139610511565b90529052905090565b604081565b600054610100900460ff168061032a575061032a61058a565b80610338575060005460ff16155b6103545760405162461bcd60e51b81526004016101f490610a38565b600054610100900460ff1615801561037f576000805460ff1961ff0019909116610100171660011790555b61038761059b565b6103926000336101fd565b80156103a4576000805461ff00191690555b50565b60008281526033602052604081206103bf9083610619565b90505b92915050565b60008281526033602052604081206103bf9083610625565b600081565b601381565b60008181526033602052604081206103c29061063a565b60008281526033602052604090206002015461041f9061015d61043b565b6102435760405162461bcd60e51b81526004016101f4906109e8565b3390565b60008281526033602052604090206104579082610645565b156102075761046461043b565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206104c0908261065a565b15610207576104cd61043b565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008060409050600060208451601f018161052857fe5b0460010190506000825160005b8381101561055157602081028781015190830152600101610535565b50602081848202816013600019fa905194509050806105825760405162461bcd60e51b81526004016101f490610a86565b505050919050565b60006105953061066f565b15905090565b600054610100900460ff16806105b457506105b461058a565b806105c2575060005460ff16155b6105de5760405162461bcd60e51b81526004016101f490610a38565b600054610100900460ff16158015610609576000805460ff1961ff0019909116610100171660011790555b610611610675565b610392610675565b60006103bf83836106f6565b60006103bf836001600160a01b03841661073b565b60006103c282610753565b60006103bf836001600160a01b038416610757565b60006103bf836001600160a01b0384166107a1565b3b151590565b600054610100900460ff168061068e575061068e61058a565b8061069c575060005460ff16155b6106b85760405162461bcd60e51b81526004016101f490610a38565b600054610100900460ff16158015610392576000805460ff1961ff00199091166101001716600117905580156103a4576000805461ff001916905550565b815460009082106107195760405162461bcd60e51b81526004016101f490610957565b82600001828154811061072857fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000610763838361073b565b610799575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103c2565b5060006103c2565b6000818152600183016020526040812054801561085d57835460001980830191908101906000908790839081106107d457fe5b90600052602060002001549050808760000184815481106107f157fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061082157fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506103c2565b60009150506103c2565b5092915050565b6040518060400160405280610881610893565b815260200161088e610893565b905290565b604051806040016040528060008152602001600081525090565b6000602082840312156108be578081fd5b5035919050565b600080604083850312156108d7578081fd5b8235915060208301356001600160a01b03811681146108f4578182fd5b809150509250929050565b60008060408385031215610911578182fd5b50508035926020909101359150565b80518252602090810151910152565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526019908201527f47657420636f6e6669672075696e74323536206661696c656400000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b6000608082019050610b1f828451610920565b6020830151610867604084018261092056fe736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657930736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657933736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657932736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657931a264697066735822122053629a129ff1abe9c9555f5979234152217ffc755596b6e5bc41be252073a65e64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80639010d07c116100715780639010d07c1461012f57806391d148541461014f578063a217fddf1461016f578063ab2a585314610177578063ca15c8731461017f578063d547741f14610192576100b4565b8063248a9ca3146100b95780632f2ff15d146100e257806336568abe146100f7578063554ef7a61461010a578063573c8aba1461011f5780638129fc1c14610127575b600080fd5b6100cc6100c73660046108ad565b6101a5565b6040516100d9919061094e565b60405180910390f35b6100f56100f03660046108c5565b6101ba565b005b6100f56101053660046108c5565b61020b565b61011261024d565b6040516100d99190610b0c565b6100cc61030c565b6100f5610311565b61014261013d3660046108ff565b6103a7565b6040516100d9919061092f565b61016261015d3660046108c5565b6103c8565b6040516100d99190610943565b6100cc6103e0565b6100cc6103e5565b6100cc61018d3660046108ad565b6103ea565b6100f56101a03660046108c5565b610401565b60009081526033602052604090206002015490565b6000828152603360205260409020600201546101d89061015d61043b565b6101fd5760405162461bcd60e51b81526004016101f490610999565b60405180910390fd5b610207828261043f565b5050565b61021361043b565b6001600160a01b0316816001600160a01b0316146102435760405162461bcd60e51b81526004016101f490610abd565b61020782826104a8565b61025561086e565b6040805160e0810182526034608082018181529192839290830191829161028391610b3260a0870139610511565b81526020016102a9604051806060016040528060348152602001610bce60349139610511565b815250815260200160405180604001604052806102dd604051806060016040528060348152602001610b9a60349139610511565b8152602001610303604051806060016040528060348152602001610b6660349139610511565b90529052905090565b604081565b600054610100900460ff168061032a575061032a61058a565b80610338575060005460ff16155b6103545760405162461bcd60e51b81526004016101f490610a38565b600054610100900460ff1615801561037f576000805460ff1961ff0019909116610100171660011790555b61038761059b565b6103926000336101fd565b80156103a4576000805461ff00191690555b50565b60008281526033602052604081206103bf9083610619565b90505b92915050565b60008281526033602052604081206103bf9083610625565b600081565b601381565b60008181526033602052604081206103c29061063a565b60008281526033602052604090206002015461041f9061015d61043b565b6102435760405162461bcd60e51b81526004016101f4906109e8565b3390565b60008281526033602052604090206104579082610645565b156102075761046461043b565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206104c0908261065a565b15610207576104cd61043b565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008060409050600060208451601f018161052857fe5b0460010190506000825160005b8381101561055157602081028781015190830152600101610535565b50602081848202816013600019fa905194509050806105825760405162461bcd60e51b81526004016101f490610a86565b505050919050565b60006105953061066f565b15905090565b600054610100900460ff16806105b457506105b461058a565b806105c2575060005460ff16155b6105de5760405162461bcd60e51b81526004016101f490610a38565b600054610100900460ff16158015610609576000805460ff1961ff0019909116610100171660011790555b610611610675565b610392610675565b60006103bf83836106f6565b60006103bf836001600160a01b03841661073b565b60006103c282610753565b60006103bf836001600160a01b038416610757565b60006103bf836001600160a01b0384166107a1565b3b151590565b600054610100900460ff168061068e575061068e61058a565b8061069c575060005460ff16155b6106b85760405162461bcd60e51b81526004016101f490610a38565b600054610100900460ff16158015610392576000805460ff1961ff00199091166101001716600117905580156103a4576000805461ff001916905550565b815460009082106107195760405162461bcd60e51b81526004016101f490610957565b82600001828154811061072857fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000610763838361073b565b610799575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103c2565b5060006103c2565b6000818152600183016020526040812054801561085d57835460001980830191908101906000908790839081106107d457fe5b90600052602060002001549050808760000184815481106107f157fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061082157fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506103c2565b60009150506103c2565b5092915050565b6040518060400160405280610881610893565b815260200161088e610893565b905290565b604051806040016040528060008152602001600081525090565b6000602082840312156108be578081fd5b5035919050565b600080604083850312156108d7578081fd5b8235915060208301356001600160a01b03811681146108f4578182fd5b809150509250929050565b60008060408385031215610911578182fd5b50508035926020909101359150565b80518252602090810151910152565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526019908201527f47657420636f6e6669672075696e74323536206661696c656400000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b6000608082019050610b1f828451610920565b6020830151610867604084018261092056fe736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657930736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657933736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657932736b616c65436f6e6669672e6e6f6465496e666f2e77616c6c6574732e696d612e636f6d6d6f6e424c535075626c69634b657931a264697066735822122053629a129ff1abe9c9555f5979234152217ffc755596b6e5bc41be252073a65e64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/MessageProxyForSchain.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/MessageProxyForSchain.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/MessageProxyForSchain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/MessageProxyForSchain.json b/predeployed/build/lib/ima_predeployed/artifacts/MessageProxyForSchain.json new file mode 100644 index 000000000..85b2c37aa --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/MessageProxyForSchain.json @@ -0,0 +1,743 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "MessageProxyForSchain", + "sourceName": "contracts/schain/MessageProxyForSchain.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "dstChainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "msgCounter", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "srcContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "dstContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "OutgoingMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "msgCounter", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "name": "PostMessageError", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "CHAIN_CONNECTOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEBUGGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_CONTRACT_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chainName", + "type": "string" + } + ], + "name": "addConnectedChain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "connectedChains", + "outputs": [ + { + "internalType": "uint256", + "name": "incomingMessageCounter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "outgoingMessageCounter", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "inited", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "fromSchainName", + "type": "string" + } + ], + "name": "getIncomingMessagesCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + } + ], + "name": "getOutgoingMessagesCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract KeyStorage", + "name": "blsKeyStorage", + "type": "address" + }, + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "isConnectedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keyStorage", + "outputs": [ + { + "internalType": "contract KeyStorage", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "moveIncomingCounter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "fromChainName", + "type": "string" + }, + { + "internalType": "uint256", + "name": "startingCounter", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "destinationContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct MessageProxyForSchain.Message[]", + "name": "messages", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "blsSignature", + "type": "uint256[2]" + }, + { + "internalType": "uint256", + "name": "hashA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hashB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + } + ], + "internalType": "struct MessageProxyForSchain.Signature", + "name": "signature", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "idxLastToPopNotIncluding", + "type": "uint256" + } + ], + "name": "postIncomingMessages", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetChainName", + "type": "string" + }, + { + "internalType": "address", + "name": "dstContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postOutgoingMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnSchain", + "type": "address" + } + ], + "name": "registerExtraContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnSchain", + "type": "address" + } + ], + "name": "registerExtraContractForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "registryContracts", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeConnectedChain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnSchain", + "type": "address" + } + ], + "name": "removeExtraContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnSchain", + "type": "address" + } + ], + "name": "removeExtraContractForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "setCountersToZero", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "string", + "name": "dstChain", + "type": "string" + }, + { + "internalType": "uint256", + "name": "msgCounter", + "type": "uint256" + }, + { + "internalType": "address", + "name": "srcContract", + "type": "address" + }, + { + "internalType": "address", + "name": "dstContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct MessageProxyForSchain.OutgoingMessageData", + "name": "message", + "type": "tuple" + } + ], + "name": "verifyOutgoingMessageData", + "outputs": [ + { + "internalType": "bool", + "name": "isValidMessage", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b506135bd806100206000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c8063999ab9aa11610104578063cab010c9116100a2578063f2f6360511610071578063f2f63605146103d7578063f399e22e146103ea578063f79f7954146103fd578063f8c88a1614610405576101da565b8063cab010c91461037c578063d547741f1461038f578063e45b045f146103a2578063e6ab8403146103b5576101da565b8063a8bb1b7d116100de578063a8bb1b7d1461033b578063ac2f861e1461034e578063b51cc14d14610356578063ca15c87314610369576101da565b8063999ab9aa1461030d578063a217fddf14610320578063a78868c814610328576101da565b80634da84ce51161017c57806377fe0f311161014b57806377fe0f31146102a75780637c5ad80c146102ba5780639010d07c146102da57806391d14854146102fa576101da565b80634da84ce514610266578063523c8ab61461027957806365e3781f1461028157806367ec602014610294576101da565b806336568abe116101b857806336568abe146102255780633b690b6b146102385780633cdd2cc3146102405780634d20385914610253576101da565b806313c52260146101df578063248a9ca3146101fd5780632f2ff15d14610210575b600080fd5b6101e7610418565b6040516101f49190612b56565b60405180910390f35b6101e761020b3660046126ad565b61043c565b61022361021e3660046126c5565b610451565b005b6102236102333660046126c5565b6104a2565b6101e76104e4565b61022361024e366004612763565b6104ea565b610223610261366004612671565b6105fa565b610223610274366004612763565b6106d3565b6101e76107a5565b61022361028f3660046127f8565b6107b7565b6101e76102a2366004612763565b61095f565b6101e76102b5366004612763565b6109cc565b6102cd6102c83660046126c5565b610a34565b6040516101f49190612b4b565b6102ed6102e83660046126f4565b610a54565b6040516101f49190612b13565b6102cd6103083660046126c5565b610a73565b6102cd61031b366004612763565b610a8b565b6101e7610ad7565b61022361033636600461287a565b610adc565b610223610349366004612671565b610d3b565b6101e7610e10565b6102cd61036436600461297a565b610e34565b6101e76103773660046126ad565b610e9b565b61022361038a3660046127a3565b610eb2565b61022361039d3660046126c5565b610fb5565b6102236103b0366004612763565b610fef565b6103c86103c33660046126ad565b6110be565b6040516101f493929190613378565b6102236103e5366004612763565b6110e2565b6102236103f8366004612715565b6111fb565b6102ed611351565b6102236104133660046127a3565b611360565b7f2785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e19181565b60009081526033602052604090206002015490565b60008281526033602052604090206002015461046f9061030861145f565b6104945760405162461bcd60e51b815260040161048b90612c81565b60405180910390fd5b61049e8282611464565b5050565b6104aa61145f565b6001600160a01b0316816001600160a01b0316146104da5760405162461bcd60e51b815260040161048b90613329565b61049e82826114cd565b60665481565b6105147f2785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e19133610a73565b6105305760405162461bcd60e51b815260040161048b90612d48565b60008282604051602001610545929190612ad4565b60405160208183030381529060405280519060200120905060405160200161056c90612b00565b604051602081830303815290604052805190602001208114156105a15760405162461bcd60e51b815260040161048b906132e0565b60008181526067602052604090206002015460ff166105d25760405162461bcd60e51b815260040161048b906131cf565b60009081526067602052604081208181556001810191909155600201805460ff191690555050565b61061260008051602061350283398151915233610a73565b61062e5760405162461bcd60e51b815260040161048b90612d7d565b610640816001600160a01b0316611536565b61065c5760405162461bcd60e51b815260040161048b90613265565b6001600160a01b0381166000908152600080516020613568833981519152602052604090205460ff16156106a25760405162461bcd60e51b815260040161048b9061329c565b6001600160a01b0316600090815260008051602061356883398151915260205260409020805460ff19166001179055565b6106fd7f621a88c2734d2b469650b9ed1f143b5eea096e7e7bb5c68a326ac7aee5e7f94633610a73565b6107195760405162461bcd60e51b815260040161048b9061322e565b6000606760008484604051602001610732929190612ad4565b604051602081830303815290604052805190602001208152602001908152602001600020600001819055506000606760008484604051602001610776929190612ad4565b604051602081830303815290604052805190602001208152602001908152602001600020600101819055505050565b60008051602061350283398151915281565b600085856040516020016107cc929190612ad4565b60408051601f1981840301815291815281516020928301206000818152606790935291206002015490915060ff166108165760405162461bcd60e51b815260040161048b9061312f565b336000908152600080516020613568833981519152602052604090205460ff168061085a57506000818152606b6020908152604080832033845290915290205460ff165b6108765760405162461bcd60e51b815260040161048b90612d07565b60008181526067602052604090206001908101546108939161153c565b60008281526067602090815260409182902060010192909255805160c0601f89018490049093028101830190915260a08101878152610957928291908a908a908190850183828082843760009201829052509385525050508481526067602090815260409182902060010154600019018184015233828401526001600160a01b03891660608401528151601f880182900482028101820190925286825260809092019187908790819084018382808284376000920191909152505050915250611561565b505050505050565b6000808383604051602001610975929190612ad4565b60408051601f1981840301815291815281516020928301206000818152606790935291206002015490915060ff166109b15760009150506109c6565b60009081526067602052604090206001015490505b92915050565b60008083836040516020016109e2929190612ad4565b60408051601f1981840301815291815281516020928301206000818152606790935291206002015490915060ff16610a1e5760009150506109c6565b6000908152606760205260409020549392505050565b606b60209081526000928352604080842090915290825290205460ff1681565b6000828152603360205260408120610a6c9083611636565b9392505050565b6000828152603360205260408120610a6c9083611642565b6000606760008484604051602001610aa4929190612ad4565b60408051808303601f190181529181528151602092830120835290820192909252016000206002015460ff169392505050565b600081565b60008787604051602001610af1929190612ad4565b604051602081830303815290604052805190602001209050610b1c610b168686611657565b84611746565b610b385760405162461bcd60e51b815260040161048b90612f4d565b60008181526067602052604090206002015460ff16610b695760405162461bcd60e51b815260040161048b906131cf565b6000818152606760205260409020548614610b965760405162461bcd60e51b815260040161048b90613033565b60005b84811015610cfd576000828152606b6020526040812090878784818110610bbc57fe5b9050602002810190610bce91906133d5565b610bdf906040810190602001612671565b6001600160a01b0316815260208101919091526040016000205460ff16158015610c6c57506000808052606b60205260008051602061356883398151915290878784818110610c2a57fe5b9050602002810190610c3c91906133d5565b610c4d906040810190602001612671565b6001600160a01b0316815260208101919091526040016000205460ff16155b15610cc8578087017f4b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e5960405180606001604052806026815260200161352260269139604051610cbb9190612ba6565b60405180910390a2610cf5565b610cf382878784818110610cd857fe5b9050602002810190610cea91906133d5565b896001016117f3565b505b600101610b99565b50600081815260676020526040902054610d17908561153c565b600082815260676020526040902055610d308183611958565b505050505050505050565b610d5360008051602061350283398151915233610a73565b610d6f5760405162461bcd60e51b815260040161048b90612ea0565b610d81816001600160a01b0316611536565b610d9d5760405162461bcd60e51b815260040161048b90613265565b6001600160a01b0381166000908152600080516020613568833981519152602052604090205460ff16610de25760405162461bcd60e51b815260040161048b90612fbb565b6001600160a01b0316600090815260008051602061356883398151915260205260409020805460ff19169055565b7f621a88c2734d2b469650b9ed1f143b5eea096e7e7bb5c68a326ac7aee5e7f94681565b6000808260000151604051602001610e4c9190612ae4565b60408051601f198184030181529181528151602092830120600081815260688452828120878501518252909352912054909150610e88846119e4565b811415610e9457600192505b5050919050565b60008181526033602052604081206109c690611a77565b60008383604051602001610ec7929190612ad4565b604051602081830303815290604052805190602001209050610ef760008051602061350283398151915233610a73565b610f135760405162461bcd60e51b815260040161048b90613090565b610f25826001600160a01b0316611536565b610f415760405162461bcd60e51b815260040161048b90613265565b6000818152606b602090815260408083206001600160a01b038616845290915290205460ff1615610f845760405162461bcd60e51b815260040161048b9061329c565b6000908152606b602090815260408083206001600160a01b03909416835292905220805460ff191660011790555050565b600082815260336020526040902060020154610fd39061030861145f565b6104da5760405162461bcd60e51b815260040161048b90612efd565b6110197f621a88c2734d2b469650b9ed1f143b5eea096e7e7bb5c68a326ac7aee5e7f94633610a73565b6110355760405162461bcd60e51b815260040161048b9061322e565b61107d6001606760008585604051602001611051929190612ad4565b60408051601f19818403018152918152815160209283012083529082019290925201600020549061153c565b606760008484604051602001611094929190612ad4565b60408051601f19818403018152918152815160209283012083529082019290925201600020555050565b60676020526000908152604090208054600182015460029092015490919060ff1683565b61110c7f2785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e19133610a73565b6111285760405162461bcd60e51b815260040161048b90612d48565b6000828260405160200161113d929190612ad4565b6040516020818303038152906040528051906020012090506066548114156111775760405162461bcd60e51b815260040161048b90612c4a565b60008181526067602052604090206002015460ff16156111a95760405162461bcd60e51b815260040161048b90612f84565b604080516060810182526000808252602080830182815260018486018181529684526067909252939091209151825591519181019190915590516002909101805460ff19169115159190911790555050565b600054610100900460ff16806112145750611214611a82565b80611222575060005460ff16155b61123e5760405162461bcd60e51b815260040161048b906130e1565b600054610100900460ff16158015611269576000805460ff1961ff0019909116610100171660011790555b611271611a93565b61127c600033610494565b606580546001600160a01b0319166001600160a01b0385161790556040805160608101825260008082526020808301829052600183850152925191926067926112c59101612b00565b60408051808303601f19018152918152815160209283012083528282019390935290820160002083518155838201516001820155928201516002909301805460ff1916931515939093179092555161131f91849101612ae4565b60408051601f198184030181529190528051602090910120606655801561134c576000805461ff00191690555b505050565b6065546001600160a01b031681565b60008383604051602001611375929190612ad4565b6040516020818303038152906040528051906020012090506113a560008051602061350283398151915233610a73565b6113c15760405162461bcd60e51b815260040161048b90612bfb565b6113d3826001600160a01b0316611536565b6113ef5760405162461bcd60e51b815260040161048b90613265565b6000818152606b602090815260408083206001600160a01b038616845290915290205460ff166114315760405162461bcd60e51b815260040161048b90612fbb565b6000908152606b602090815260408083206001600160a01b03909416835292905220805460ff191690555050565b335b90565b600082815260336020526040902061147c9082611b26565b1561049e5761148961145f565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206114e59082611b3b565b1561049e576114f261145f565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b3b151590565b600082820183811015610a6c5760405162461bcd60e51b815260040161048b90612cd0565b805160405160009161157591602001612ae4565b60405160208183030381529060405280519060200120905081604001516001600160a01b03168260200151827f803d7f3ca0e5f93fcce39fa29812ed57a95a151594966e17125220132741c6b0856060015186608001516040516115da929190612b27565b60405180910390a46115eb826119e4565b6000828152606860209081526040808320606a808452828520805486529184529184209490945591849052525461162390600161153c565b6000918252606a60205260409091205550565b6000610a6c8383611b50565b6000610a6c836001600160a01b038416611b95565b6000606060005b83811015611736578185858381811061167357fe5b905060200281019061168591906133d5565b611693906020810190612671565b60601b6001600160601b0319168686848181106116ac57fe5b90506020028101906116be91906133d5565b6116cf906040810190602001612671565b60601b6001600160601b0319168787858181106116e857fe5b90506020028101906116fa91906133d5565b611708906040810190613390565b60405160200161171c959493929190612a9d565b60408051601f19818403018152919052915060010161165e565b5080516020909101209392505050565b60408051808201825282358152602080840135908201526065548251632aa77bd360e11b81528351600094610a6c949388936080808a013594938a01359360608b0135936001600160a01b03169263554ef7a6926004808301939192829003018186803b1580156117b657600080fd5b505afa1580156117ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ee919061293a565b611bad565b60006118056040840160208501612671565b6001600160a01b031663884cee5a856118216020870187612671565b61182e6040880188613390565b6040518563ffffffff1660e01b815260040161184d9493929190612b5f565b602060405180830381600087803b15801561186757600080fd5b505af1925050508015611897575060408051601f3d908101601f191682019092526118949181019061268d565b60015b611950576118a3613447565b806118ae57506118f0565b827f4b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e59826040516118de9190612ba6565b60405180910390a26000915050610a6c565b3d80801561191a576040519150601f19603f3d011682016040523d82523d6000602084013e61191f565b606091505b50827f4b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e59826040516118de9190612ba6565b949350505050565b6000828152606a602090815260408083205460699092528220545b838110156119ad57818110611987576119ad565b600085815260686020908152604080832084845290915281205560019283019201611973565b5081156119dd576000848152606960205260409020546119cd908361153c565b6000858152606960205260409020555b5092915050565b6000606082600001516040516020016119fd9190612ae4565b60405160208183030381529060405280519060200120836020015160001b846040015160601b6001600160601b031916856060015160601b6001600160601b0319168660800151604051602001611a58959493929190612a62565b60408051808303601f1901815291905280516020909101209392505050565b60006109c682611ceb565b6000611a8d30611536565b15905090565b600054610100900460ff1680611aac5750611aac611a82565b80611aba575060005460ff16155b611ad65760405162461bcd60e51b815260040161048b906130e1565b600054610100900460ff16158015611b01576000805460ff1961ff0019909116610100171660011790555b611b09611cef565b611b11611cef565b8015611b23576000805461ff00191690555b50565b6000610a6c836001600160a01b038416611d70565b6000610a6c836001600160a01b038416611dba565b81546000908210611b735760405162461bcd60e51b815260040161048b90612bb9565b826000018281548110611b8257fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b6000611bb887611e80565b611bd45760405162461bcd60e51b815260040161048b90612e11565b611be086868686611eb6565b611bec57506000611ce1565b6000611bfb8860200151611f88565b9050611c0b886000015182611fac565b611c275760405162461bcd60e51b815260040161048b90613206565b611c318585611fac565b611c4d5760405162461bcd60e51b815260040161048b90612e41565b611c556124f2565b611c5d611fdc565b9050611c688461209c565b611c845760405162461bcd60e51b815260040161048b906131a1565b611cdc8960000151838360000151602001518460000151600001518560200151602001518660200151600001518c8c8c60000151602001518d60000151600001518e60200151602001518f60200151600001516120b0565b925050505b9695505050505050565b5490565b600054610100900460ff1680611d085750611d08611a82565b80611d16575060005460ff16155b611d325760405162461bcd60e51b815260040161048b906130e1565b600054610100900460ff16158015611b11576000805460ff1961ff0019909116610100171660011790558015611b23576000805461ff001916905550565b6000611d7c8383611b95565b611db2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109c6565b5060006109c6565b60008181526001830160205260408120548015611e765783546000198083019190810190600090879083908110611ded57fe5b9060005260206000200154905080876000018481548110611e0a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611e3a57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506109c6565b60009150506109c6565b600060008051602061354883398151915282600001511080156109c6575050602001516000805160206135488339815191521190565b60006064841115611ec957506000611950565b60008051602061354883398151915280860690611ee6828761153c565b81611eed57fe5b069050600060008051602061354883398151915260036000805160206135488339815191528460008051602061354883398151915286870909089050611f426000805160206135488339815191526002612159565b841080611f6057508060008051602061354883398151915285860914155b80611f6b5750848214155b15611f7b57600092505050611950565b5060019695505050505050565b60006109c6600080516020613548833981519152611fa6818561218b565b906121b3565b600060008051602061354883398151915280600381868188890909088180611fd057fe5b84850914949350505050565b611fe46124f2565b50604080516080810182527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed8183019081527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26060830152815281518083019092527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa82527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60208381019190915281019190915290565b60006109c6826000015183602001516121e5565b6000806120bb612517565b8e8152602081018e9052604081018d9052606081018c9052608081018b905260a081018a905260c0810189905260e081018890526101008101879052610120810186905261014081018590526101608101849052612117612536565b602081610180846008600019fa9250826121435760405162461bcd60e51b815260040161048b90613173565b5115159f9e505050505050505050505050505050565b600080821161217a5760405162461bcd60e51b815260040161048b90612e69565b81838161218357fe5b049392505050565b6000828211156121ad5760405162461bcd60e51b815260040161048b90612dda565b50900390565b60008082116121d45760405162461bcd60e51b815260040161048b90612ffc565b8183816121dd57fe5b069392505050565b60006121f18383612264565b156121fe575060016109c6565b612206612554565b61220f83612297565b9050612219612554565b61224761222461231c565b61224161223a886122348a612297565b9061237a565b859061243e565b9061243e565b805190915015801561225b57506020810151155b95945050505050565b815160009015801561227857506020830151155b8015612285575081516001145b8015610a6c5750506020015115919050565b61229f612554565b60008051602061354883398151915260008160208501518551099050600082806122c557fe5b83806122cd57fe5b84806122d557fe5b8760200151600187030987510884806122ea57fe5b60208801518851080990506040518060400160405280828152602001848061230e57fe5b848508905295945050505050565b612324612554565b50604080518082019091527f2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e581527e9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2602082015290565b612382612554565b600080516020613548833981519152612399612554565b604051806040016040528083806123ac57fe5b8651885109815260200183806123be57fe5b86602001518860200151099052905081806123d557fe5b82806123dd57fe5b82602001516001850309825108835281806123f457fe5b82806123fc57fe5b60208301518351088303838061240e57fe5b848061241657fe5b6020880151885108858061242657fe5b60208a01518a51080908602084015250909392505050565b612446612554565b81518351600080516020613548833981519152911161247757808061246757fe5b8351855190830390088252612497565b61249481828061248357fe5b8651865190850390088303906121b3565b82525b82602001518460200151106124c55780806124ae57fe5b8360200151820385602001510860208301526119dd565b6124e68182806124d157fe5b866020015184038660200151088303906121b3565b60208301525092915050565b6040518060400160405280612505612554565b8152602001612512612554565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b604051806040016040528060008152602001600081525090565b80356109c6816134ec565b60008083601f84011261258a578182fd5b50813567ffffffffffffffff8111156125a1578182fd5b6020830191508360208285010111156125b957600080fd5b9250929050565b600082601f8301126125d0578081fd5b813567ffffffffffffffff8111156125e6578182fd5b6125f9601f8201601f19166020016133ea565b915080825283602082850101111561261057600080fd5b8060208401602084013760009082016020015292915050565b60006040828403121561263a578081fd5b61264460406133ea565b9050815181526020820151602082015292915050565b600060a0828403121561266b578081fd5b50919050565b600060208284031215612682578081fd5b8135610a6c816134ec565b60006020828403121561269e578081fd5b81518015158114610a6c578182fd5b6000602082840312156126be578081fd5b5035919050565b600080604083850312156126d7578081fd5b8235915060208301356126e9816134ec565b809150509250929050565b60008060408385031215612706578182fd5b50508035926020909101359150565b60008060408385031215612727578182fd5b8235612732816134ec565b9150602083013567ffffffffffffffff81111561274d578182fd5b612759858286016125c0565b9150509250929050565b60008060208385031215612775578182fd5b823567ffffffffffffffff81111561278b578283fd5b61279785828601612579565b90969095509350505050565b6000806000604084860312156127b7578081fd5b833567ffffffffffffffff8111156127cd578182fd5b6127d986828701612579565b90945092505060208401356127ed816134ec565b809150509250925092565b60008060008060006060868803121561280f578081fd5b853567ffffffffffffffff80821115612826578283fd5b61283289838a01612579565b909750955060208801359150612847826134ec565b9093506040870135908082111561285c578283fd5b5061286988828901612579565b969995985093965092949392505050565b6000806000806000806000610120888a031215612895578485fd5b873567ffffffffffffffff808211156128ac578687fd5b6128b88b838c01612579565b909950975060208a0135965060408a01359150808211156128d7578384fd5b818a0191508a601f8301126128ea578384fd5b8135818111156128f8578485fd5b8b6020808302850101111561290b578485fd5b6020830196508095505050506129248960608a0161265a565b9150610100880135905092959891949750929550565b60006080828403121561294b578081fd5b61295560406133ea565b61295f8484612629565b815261296e8460408501612629565b60208201529392505050565b60006020828403121561298b578081fd5b813567ffffffffffffffff808211156129a2578283fd5b9083019060a082860312156129b5578283fd5b6129bf60a06133ea565b8235828111156129cd578485fd5b6129d9878286016125c0565b825250602083013560208201526129f3866040850161256e565b6040820152612a05866060850161256e565b6060820152608083013582811115612a1b578485fd5b612a27878286016125c0565b60808301525095945050505050565b60008151808452612a4e816020860160208601613411565b601f01601f19169290920160200192915050565b60008682528560208301528460408301528360608301528251612a8c816080850160208701613411565b919091016080019695505050505050565b60008651612aaf818460208b01613411565b8201868152602081018690528385604083013790920160400191825250949350505050565b6000828483379101908152919050565b60008251612af6818460208701613411565b9190910192915050565b6613585a5b9b995d60ca1b815260070190565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020820181905260009061195090830184612a36565b901515815260200190565b90815260200190565b8481526001600160a01b03841660208201526060604082018190528101829052600082846080840137818301608090810191909152601f909201601f191601019392505050565b600060208252610a6c6020830184612a36565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2072656d6f766560408201526e08195e1d1c984818dbdb9d1c9858dd608a1b606082015260800190565b6020808252601c908201527f53636861696e2063616e6e6f7420636f6e6e65637420697473656c6600000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f53656e64657220636f6e7472616374206973206e6f74207265676973746572656040820152601960fa1b606082015260800190565b6020808252818101527f434841494e5f434f4e4e4543544f525f524f4c45206973207265717569726564604082015260600190565b60208082526039908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2072656769737460408201527f657220657874726120636f6e747261637420666f7220616c6c00000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526016908201527514da59db985d1d5c99481a5cc81b9bdd081d985b1a5960521b604082015260600190565b6020808252600e908201526d48617368206e6f7420696e20473160901b604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526037908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2072656d6f766560408201527f20657874726120636f6e747261637420666f7220616c6c000000000000000000606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526019908201527f5369676e6174757265206973206e6f7420766572696669656400000000000000604082015260600190565b6020808252601a908201527f436861696e20697320616c726561647920636f6e6e6563746564000000000000604082015260600190565b60208082526021908201527f457874726120636f6e747261637420697320616c72656164792072656d6f76656040820152601960fa1b606082015260800190565b60208082526018908201527f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000604082015260600190565b60208082526038908201527f5374617274696e6720636f756e746572206973206e6f74207175616c20746f2060408201527f696e636f6d696e67206d65737361676520636f756e7465720000000000000000606082015260800190565b60208082526031908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f20726567697374604082015270195c88195e1d1c984818dbdb9d1c9858dd607a1b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526024908201527f44657374696e6174696f6e20636861696e206973206e6f7420696e697469616c6040820152631a5e995960e21b606082015260800190565b60208082526014908201527314185a5c9a5b99c818da1958dac819985a5b195960621b604082015260600190565b602080825260149082015273283ab13634b19025b2bc903737ba1034b710239960611b604082015260600190565b60208082526018908201527f436861696e206973206e6f7420696e697469616c697a65640000000000000000604082015260600190565b6020808252600e908201526d5369676e206e6f7420696e20473160901b604082015260600190565b60208082526019908201527f44454255474745525f524f4c4520697320726571756972656400000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b60208082526024908201527f457874726120636f6e747261637420697320616c726561647920726567697374604082015263195c995960e21b606082015260800190565b60208082526029908201527f4e657720636861696e20686173682063616e6e6f7420626520657175616c20746040820152681bc813585a5b9b995d60ba1b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b92835260208301919091521515604082015260600190565b6000808335601e198436030181126133a6578283fd5b83018035915067ffffffffffffffff8211156133c0578283fd5b6020019150368190038213156125b957600080fd5b60008235605e19833603018112612af6578182fd5b60405181810167ffffffffffffffff8111828210171561340957600080fd5b604052919050565b60005b8381101561342c578181015183820152602001613414565b8381111561343b576000848401525b50505050565b60e01c90565b600060443d101561345757611461565b600481823e6308c379a061346b8251613441565b1461347557611461565b6040513d600319016004823e80513d67ffffffffffffffff81602484011181841117156134a55750505050611461565b828401925082519150808211156134bf5750505050611461565b503d830160208284010111156134d757505050611461565b601f01601f1916810160200160405291505090565b6001600160a01b0381168114611b2357600080fdfe6155b5aac15ce9aa193c0527a6f43be0a36a7e2e7496c2b615c0e5f92284277344657374696e6174696f6e20636f6e7472616374206973206e6f74207265676973746572656430644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47c8cc8bda7ad4886bea3ebbdafa02e79d37c39bf4011696b26a31a0802fd9458ba2646970667358221220093c2d278aeb4ed3411e26a3f398981ce473e254dc3a9b827a467e2847a66c6d64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101da5760003560e01c8063999ab9aa11610104578063cab010c9116100a2578063f2f6360511610071578063f2f63605146103d7578063f399e22e146103ea578063f79f7954146103fd578063f8c88a1614610405576101da565b8063cab010c91461037c578063d547741f1461038f578063e45b045f146103a2578063e6ab8403146103b5576101da565b8063a8bb1b7d116100de578063a8bb1b7d1461033b578063ac2f861e1461034e578063b51cc14d14610356578063ca15c87314610369576101da565b8063999ab9aa1461030d578063a217fddf14610320578063a78868c814610328576101da565b80634da84ce51161017c57806377fe0f311161014b57806377fe0f31146102a75780637c5ad80c146102ba5780639010d07c146102da57806391d14854146102fa576101da565b80634da84ce514610266578063523c8ab61461027957806365e3781f1461028157806367ec602014610294576101da565b806336568abe116101b857806336568abe146102255780633b690b6b146102385780633cdd2cc3146102405780634d20385914610253576101da565b806313c52260146101df578063248a9ca3146101fd5780632f2ff15d14610210575b600080fd5b6101e7610418565b6040516101f49190612b56565b60405180910390f35b6101e761020b3660046126ad565b61043c565b61022361021e3660046126c5565b610451565b005b6102236102333660046126c5565b6104a2565b6101e76104e4565b61022361024e366004612763565b6104ea565b610223610261366004612671565b6105fa565b610223610274366004612763565b6106d3565b6101e76107a5565b61022361028f3660046127f8565b6107b7565b6101e76102a2366004612763565b61095f565b6101e76102b5366004612763565b6109cc565b6102cd6102c83660046126c5565b610a34565b6040516101f49190612b4b565b6102ed6102e83660046126f4565b610a54565b6040516101f49190612b13565b6102cd6103083660046126c5565b610a73565b6102cd61031b366004612763565b610a8b565b6101e7610ad7565b61022361033636600461287a565b610adc565b610223610349366004612671565b610d3b565b6101e7610e10565b6102cd61036436600461297a565b610e34565b6101e76103773660046126ad565b610e9b565b61022361038a3660046127a3565b610eb2565b61022361039d3660046126c5565b610fb5565b6102236103b0366004612763565b610fef565b6103c86103c33660046126ad565b6110be565b6040516101f493929190613378565b6102236103e5366004612763565b6110e2565b6102236103f8366004612715565b6111fb565b6102ed611351565b6102236104133660046127a3565b611360565b7f2785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e19181565b60009081526033602052604090206002015490565b60008281526033602052604090206002015461046f9061030861145f565b6104945760405162461bcd60e51b815260040161048b90612c81565b60405180910390fd5b61049e8282611464565b5050565b6104aa61145f565b6001600160a01b0316816001600160a01b0316146104da5760405162461bcd60e51b815260040161048b90613329565b61049e82826114cd565b60665481565b6105147f2785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e19133610a73565b6105305760405162461bcd60e51b815260040161048b90612d48565b60008282604051602001610545929190612ad4565b60405160208183030381529060405280519060200120905060405160200161056c90612b00565b604051602081830303815290604052805190602001208114156105a15760405162461bcd60e51b815260040161048b906132e0565b60008181526067602052604090206002015460ff166105d25760405162461bcd60e51b815260040161048b906131cf565b60009081526067602052604081208181556001810191909155600201805460ff191690555050565b61061260008051602061350283398151915233610a73565b61062e5760405162461bcd60e51b815260040161048b90612d7d565b610640816001600160a01b0316611536565b61065c5760405162461bcd60e51b815260040161048b90613265565b6001600160a01b0381166000908152600080516020613568833981519152602052604090205460ff16156106a25760405162461bcd60e51b815260040161048b9061329c565b6001600160a01b0316600090815260008051602061356883398151915260205260409020805460ff19166001179055565b6106fd7f621a88c2734d2b469650b9ed1f143b5eea096e7e7bb5c68a326ac7aee5e7f94633610a73565b6107195760405162461bcd60e51b815260040161048b9061322e565b6000606760008484604051602001610732929190612ad4565b604051602081830303815290604052805190602001208152602001908152602001600020600001819055506000606760008484604051602001610776929190612ad4565b604051602081830303815290604052805190602001208152602001908152602001600020600101819055505050565b60008051602061350283398151915281565b600085856040516020016107cc929190612ad4565b60408051601f1981840301815291815281516020928301206000818152606790935291206002015490915060ff166108165760405162461bcd60e51b815260040161048b9061312f565b336000908152600080516020613568833981519152602052604090205460ff168061085a57506000818152606b6020908152604080832033845290915290205460ff165b6108765760405162461bcd60e51b815260040161048b90612d07565b60008181526067602052604090206001908101546108939161153c565b60008281526067602090815260409182902060010192909255805160c0601f89018490049093028101830190915260a08101878152610957928291908a908a908190850183828082843760009201829052509385525050508481526067602090815260409182902060010154600019018184015233828401526001600160a01b03891660608401528151601f880182900482028101820190925286825260809092019187908790819084018382808284376000920191909152505050915250611561565b505050505050565b6000808383604051602001610975929190612ad4565b60408051601f1981840301815291815281516020928301206000818152606790935291206002015490915060ff166109b15760009150506109c6565b60009081526067602052604090206001015490505b92915050565b60008083836040516020016109e2929190612ad4565b60408051601f1981840301815291815281516020928301206000818152606790935291206002015490915060ff16610a1e5760009150506109c6565b6000908152606760205260409020549392505050565b606b60209081526000928352604080842090915290825290205460ff1681565b6000828152603360205260408120610a6c9083611636565b9392505050565b6000828152603360205260408120610a6c9083611642565b6000606760008484604051602001610aa4929190612ad4565b60408051808303601f190181529181528151602092830120835290820192909252016000206002015460ff169392505050565b600081565b60008787604051602001610af1929190612ad4565b604051602081830303815290604052805190602001209050610b1c610b168686611657565b84611746565b610b385760405162461bcd60e51b815260040161048b90612f4d565b60008181526067602052604090206002015460ff16610b695760405162461bcd60e51b815260040161048b906131cf565b6000818152606760205260409020548614610b965760405162461bcd60e51b815260040161048b90613033565b60005b84811015610cfd576000828152606b6020526040812090878784818110610bbc57fe5b9050602002810190610bce91906133d5565b610bdf906040810190602001612671565b6001600160a01b0316815260208101919091526040016000205460ff16158015610c6c57506000808052606b60205260008051602061356883398151915290878784818110610c2a57fe5b9050602002810190610c3c91906133d5565b610c4d906040810190602001612671565b6001600160a01b0316815260208101919091526040016000205460ff16155b15610cc8578087017f4b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e5960405180606001604052806026815260200161352260269139604051610cbb9190612ba6565b60405180910390a2610cf5565b610cf382878784818110610cd857fe5b9050602002810190610cea91906133d5565b896001016117f3565b505b600101610b99565b50600081815260676020526040902054610d17908561153c565b600082815260676020526040902055610d308183611958565b505050505050505050565b610d5360008051602061350283398151915233610a73565b610d6f5760405162461bcd60e51b815260040161048b90612ea0565b610d81816001600160a01b0316611536565b610d9d5760405162461bcd60e51b815260040161048b90613265565b6001600160a01b0381166000908152600080516020613568833981519152602052604090205460ff16610de25760405162461bcd60e51b815260040161048b90612fbb565b6001600160a01b0316600090815260008051602061356883398151915260205260409020805460ff19169055565b7f621a88c2734d2b469650b9ed1f143b5eea096e7e7bb5c68a326ac7aee5e7f94681565b6000808260000151604051602001610e4c9190612ae4565b60408051601f198184030181529181528151602092830120600081815260688452828120878501518252909352912054909150610e88846119e4565b811415610e9457600192505b5050919050565b60008181526033602052604081206109c690611a77565b60008383604051602001610ec7929190612ad4565b604051602081830303815290604052805190602001209050610ef760008051602061350283398151915233610a73565b610f135760405162461bcd60e51b815260040161048b90613090565b610f25826001600160a01b0316611536565b610f415760405162461bcd60e51b815260040161048b90613265565b6000818152606b602090815260408083206001600160a01b038616845290915290205460ff1615610f845760405162461bcd60e51b815260040161048b9061329c565b6000908152606b602090815260408083206001600160a01b03909416835292905220805460ff191660011790555050565b600082815260336020526040902060020154610fd39061030861145f565b6104da5760405162461bcd60e51b815260040161048b90612efd565b6110197f621a88c2734d2b469650b9ed1f143b5eea096e7e7bb5c68a326ac7aee5e7f94633610a73565b6110355760405162461bcd60e51b815260040161048b9061322e565b61107d6001606760008585604051602001611051929190612ad4565b60408051601f19818403018152918152815160209283012083529082019290925201600020549061153c565b606760008484604051602001611094929190612ad4565b60408051601f19818403018152918152815160209283012083529082019290925201600020555050565b60676020526000908152604090208054600182015460029092015490919060ff1683565b61110c7f2785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e19133610a73565b6111285760405162461bcd60e51b815260040161048b90612d48565b6000828260405160200161113d929190612ad4565b6040516020818303038152906040528051906020012090506066548114156111775760405162461bcd60e51b815260040161048b90612c4a565b60008181526067602052604090206002015460ff16156111a95760405162461bcd60e51b815260040161048b90612f84565b604080516060810182526000808252602080830182815260018486018181529684526067909252939091209151825591519181019190915590516002909101805460ff19169115159190911790555050565b600054610100900460ff16806112145750611214611a82565b80611222575060005460ff16155b61123e5760405162461bcd60e51b815260040161048b906130e1565b600054610100900460ff16158015611269576000805460ff1961ff0019909116610100171660011790555b611271611a93565b61127c600033610494565b606580546001600160a01b0319166001600160a01b0385161790556040805160608101825260008082526020808301829052600183850152925191926067926112c59101612b00565b60408051808303601f19018152918152815160209283012083528282019390935290820160002083518155838201516001820155928201516002909301805460ff1916931515939093179092555161131f91849101612ae4565b60408051601f198184030181529190528051602090910120606655801561134c576000805461ff00191690555b505050565b6065546001600160a01b031681565b60008383604051602001611375929190612ad4565b6040516020818303038152906040528051906020012090506113a560008051602061350283398151915233610a73565b6113c15760405162461bcd60e51b815260040161048b90612bfb565b6113d3826001600160a01b0316611536565b6113ef5760405162461bcd60e51b815260040161048b90613265565b6000818152606b602090815260408083206001600160a01b038616845290915290205460ff166114315760405162461bcd60e51b815260040161048b90612fbb565b6000908152606b602090815260408083206001600160a01b03909416835292905220805460ff191690555050565b335b90565b600082815260336020526040902061147c9082611b26565b1561049e5761148961145f565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206114e59082611b3b565b1561049e576114f261145f565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b3b151590565b600082820183811015610a6c5760405162461bcd60e51b815260040161048b90612cd0565b805160405160009161157591602001612ae4565b60405160208183030381529060405280519060200120905081604001516001600160a01b03168260200151827f803d7f3ca0e5f93fcce39fa29812ed57a95a151594966e17125220132741c6b0856060015186608001516040516115da929190612b27565b60405180910390a46115eb826119e4565b6000828152606860209081526040808320606a808452828520805486529184529184209490945591849052525461162390600161153c565b6000918252606a60205260409091205550565b6000610a6c8383611b50565b6000610a6c836001600160a01b038416611b95565b6000606060005b83811015611736578185858381811061167357fe5b905060200281019061168591906133d5565b611693906020810190612671565b60601b6001600160601b0319168686848181106116ac57fe5b90506020028101906116be91906133d5565b6116cf906040810190602001612671565b60601b6001600160601b0319168787858181106116e857fe5b90506020028101906116fa91906133d5565b611708906040810190613390565b60405160200161171c959493929190612a9d565b60408051601f19818403018152919052915060010161165e565b5080516020909101209392505050565b60408051808201825282358152602080840135908201526065548251632aa77bd360e11b81528351600094610a6c949388936080808a013594938a01359360608b0135936001600160a01b03169263554ef7a6926004808301939192829003018186803b1580156117b657600080fd5b505afa1580156117ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ee919061293a565b611bad565b60006118056040840160208501612671565b6001600160a01b031663884cee5a856118216020870187612671565b61182e6040880188613390565b6040518563ffffffff1660e01b815260040161184d9493929190612b5f565b602060405180830381600087803b15801561186757600080fd5b505af1925050508015611897575060408051601f3d908101601f191682019092526118949181019061268d565b60015b611950576118a3613447565b806118ae57506118f0565b827f4b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e59826040516118de9190612ba6565b60405180910390a26000915050610a6c565b3d80801561191a576040519150601f19603f3d011682016040523d82523d6000602084013e61191f565b606091505b50827f4b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e59826040516118de9190612ba6565b949350505050565b6000828152606a602090815260408083205460699092528220545b838110156119ad57818110611987576119ad565b600085815260686020908152604080832084845290915281205560019283019201611973565b5081156119dd576000848152606960205260409020546119cd908361153c565b6000858152606960205260409020555b5092915050565b6000606082600001516040516020016119fd9190612ae4565b60405160208183030381529060405280519060200120836020015160001b846040015160601b6001600160601b031916856060015160601b6001600160601b0319168660800151604051602001611a58959493929190612a62565b60408051808303601f1901815291905280516020909101209392505050565b60006109c682611ceb565b6000611a8d30611536565b15905090565b600054610100900460ff1680611aac5750611aac611a82565b80611aba575060005460ff16155b611ad65760405162461bcd60e51b815260040161048b906130e1565b600054610100900460ff16158015611b01576000805460ff1961ff0019909116610100171660011790555b611b09611cef565b611b11611cef565b8015611b23576000805461ff00191690555b50565b6000610a6c836001600160a01b038416611d70565b6000610a6c836001600160a01b038416611dba565b81546000908210611b735760405162461bcd60e51b815260040161048b90612bb9565b826000018281548110611b8257fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b6000611bb887611e80565b611bd45760405162461bcd60e51b815260040161048b90612e11565b611be086868686611eb6565b611bec57506000611ce1565b6000611bfb8860200151611f88565b9050611c0b886000015182611fac565b611c275760405162461bcd60e51b815260040161048b90613206565b611c318585611fac565b611c4d5760405162461bcd60e51b815260040161048b90612e41565b611c556124f2565b611c5d611fdc565b9050611c688461209c565b611c845760405162461bcd60e51b815260040161048b906131a1565b611cdc8960000151838360000151602001518460000151600001518560200151602001518660200151600001518c8c8c60000151602001518d60000151600001518e60200151602001518f60200151600001516120b0565b925050505b9695505050505050565b5490565b600054610100900460ff1680611d085750611d08611a82565b80611d16575060005460ff16155b611d325760405162461bcd60e51b815260040161048b906130e1565b600054610100900460ff16158015611b11576000805460ff1961ff0019909116610100171660011790558015611b23576000805461ff001916905550565b6000611d7c8383611b95565b611db2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109c6565b5060006109c6565b60008181526001830160205260408120548015611e765783546000198083019190810190600090879083908110611ded57fe5b9060005260206000200154905080876000018481548110611e0a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611e3a57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506109c6565b60009150506109c6565b600060008051602061354883398151915282600001511080156109c6575050602001516000805160206135488339815191521190565b60006064841115611ec957506000611950565b60008051602061354883398151915280860690611ee6828761153c565b81611eed57fe5b069050600060008051602061354883398151915260036000805160206135488339815191528460008051602061354883398151915286870909089050611f426000805160206135488339815191526002612159565b841080611f6057508060008051602061354883398151915285860914155b80611f6b5750848214155b15611f7b57600092505050611950565b5060019695505050505050565b60006109c6600080516020613548833981519152611fa6818561218b565b906121b3565b600060008051602061354883398151915280600381868188890909088180611fd057fe5b84850914949350505050565b611fe46124f2565b50604080516080810182527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed8183019081527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26060830152815281518083019092527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa82527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60208381019190915281019190915290565b60006109c6826000015183602001516121e5565b6000806120bb612517565b8e8152602081018e9052604081018d9052606081018c9052608081018b905260a081018a905260c0810189905260e081018890526101008101879052610120810186905261014081018590526101608101849052612117612536565b602081610180846008600019fa9250826121435760405162461bcd60e51b815260040161048b90613173565b5115159f9e505050505050505050505050505050565b600080821161217a5760405162461bcd60e51b815260040161048b90612e69565b81838161218357fe5b049392505050565b6000828211156121ad5760405162461bcd60e51b815260040161048b90612dda565b50900390565b60008082116121d45760405162461bcd60e51b815260040161048b90612ffc565b8183816121dd57fe5b069392505050565b60006121f18383612264565b156121fe575060016109c6565b612206612554565b61220f83612297565b9050612219612554565b61224761222461231c565b61224161223a886122348a612297565b9061237a565b859061243e565b9061243e565b805190915015801561225b57506020810151155b95945050505050565b815160009015801561227857506020830151155b8015612285575081516001145b8015610a6c5750506020015115919050565b61229f612554565b60008051602061354883398151915260008160208501518551099050600082806122c557fe5b83806122cd57fe5b84806122d557fe5b8760200151600187030987510884806122ea57fe5b60208801518851080990506040518060400160405280828152602001848061230e57fe5b848508905295945050505050565b612324612554565b50604080518082019091527f2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e581527e9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2602082015290565b612382612554565b600080516020613548833981519152612399612554565b604051806040016040528083806123ac57fe5b8651885109815260200183806123be57fe5b86602001518860200151099052905081806123d557fe5b82806123dd57fe5b82602001516001850309825108835281806123f457fe5b82806123fc57fe5b60208301518351088303838061240e57fe5b848061241657fe5b6020880151885108858061242657fe5b60208a01518a51080908602084015250909392505050565b612446612554565b81518351600080516020613548833981519152911161247757808061246757fe5b8351855190830390088252612497565b61249481828061248357fe5b8651865190850390088303906121b3565b82525b82602001518460200151106124c55780806124ae57fe5b8360200151820385602001510860208301526119dd565b6124e68182806124d157fe5b866020015184038660200151088303906121b3565b60208301525092915050565b6040518060400160405280612505612554565b8152602001612512612554565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b604051806040016040528060008152602001600081525090565b80356109c6816134ec565b60008083601f84011261258a578182fd5b50813567ffffffffffffffff8111156125a1578182fd5b6020830191508360208285010111156125b957600080fd5b9250929050565b600082601f8301126125d0578081fd5b813567ffffffffffffffff8111156125e6578182fd5b6125f9601f8201601f19166020016133ea565b915080825283602082850101111561261057600080fd5b8060208401602084013760009082016020015292915050565b60006040828403121561263a578081fd5b61264460406133ea565b9050815181526020820151602082015292915050565b600060a0828403121561266b578081fd5b50919050565b600060208284031215612682578081fd5b8135610a6c816134ec565b60006020828403121561269e578081fd5b81518015158114610a6c578182fd5b6000602082840312156126be578081fd5b5035919050565b600080604083850312156126d7578081fd5b8235915060208301356126e9816134ec565b809150509250929050565b60008060408385031215612706578182fd5b50508035926020909101359150565b60008060408385031215612727578182fd5b8235612732816134ec565b9150602083013567ffffffffffffffff81111561274d578182fd5b612759858286016125c0565b9150509250929050565b60008060208385031215612775578182fd5b823567ffffffffffffffff81111561278b578283fd5b61279785828601612579565b90969095509350505050565b6000806000604084860312156127b7578081fd5b833567ffffffffffffffff8111156127cd578182fd5b6127d986828701612579565b90945092505060208401356127ed816134ec565b809150509250925092565b60008060008060006060868803121561280f578081fd5b853567ffffffffffffffff80821115612826578283fd5b61283289838a01612579565b909750955060208801359150612847826134ec565b9093506040870135908082111561285c578283fd5b5061286988828901612579565b969995985093965092949392505050565b6000806000806000806000610120888a031215612895578485fd5b873567ffffffffffffffff808211156128ac578687fd5b6128b88b838c01612579565b909950975060208a0135965060408a01359150808211156128d7578384fd5b818a0191508a601f8301126128ea578384fd5b8135818111156128f8578485fd5b8b6020808302850101111561290b578485fd5b6020830196508095505050506129248960608a0161265a565b9150610100880135905092959891949750929550565b60006080828403121561294b578081fd5b61295560406133ea565b61295f8484612629565b815261296e8460408501612629565b60208201529392505050565b60006020828403121561298b578081fd5b813567ffffffffffffffff808211156129a2578283fd5b9083019060a082860312156129b5578283fd5b6129bf60a06133ea565b8235828111156129cd578485fd5b6129d9878286016125c0565b825250602083013560208201526129f3866040850161256e565b6040820152612a05866060850161256e565b6060820152608083013582811115612a1b578485fd5b612a27878286016125c0565b60808301525095945050505050565b60008151808452612a4e816020860160208601613411565b601f01601f19169290920160200192915050565b60008682528560208301528460408301528360608301528251612a8c816080850160208701613411565b919091016080019695505050505050565b60008651612aaf818460208b01613411565b8201868152602081018690528385604083013790920160400191825250949350505050565b6000828483379101908152919050565b60008251612af6818460208701613411565b9190910192915050565b6613585a5b9b995d60ca1b815260070190565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020820181905260009061195090830184612a36565b901515815260200190565b90815260200190565b8481526001600160a01b03841660208201526060604082018190528101829052600082846080840137818301608090810191909152601f909201601f191601019392505050565b600060208252610a6c6020830184612a36565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2072656d6f766560408201526e08195e1d1c984818dbdb9d1c9858dd608a1b606082015260800190565b6020808252601c908201527f53636861696e2063616e6e6f7420636f6e6e65637420697473656c6600000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f53656e64657220636f6e7472616374206973206e6f74207265676973746572656040820152601960fa1b606082015260800190565b6020808252818101527f434841494e5f434f4e4e4543544f525f524f4c45206973207265717569726564604082015260600190565b60208082526039908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2072656769737460408201527f657220657874726120636f6e747261637420666f7220616c6c00000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526016908201527514da59db985d1d5c99481a5cc81b9bdd081d985b1a5960521b604082015260600190565b6020808252600e908201526d48617368206e6f7420696e20473160901b604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526037908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2072656d6f766560408201527f20657874726120636f6e747261637420666f7220616c6c000000000000000000606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526019908201527f5369676e6174757265206973206e6f7420766572696669656400000000000000604082015260600190565b6020808252601a908201527f436861696e20697320616c726561647920636f6e6e6563746564000000000000604082015260600190565b60208082526021908201527f457874726120636f6e747261637420697320616c72656164792072656d6f76656040820152601960fa1b606082015260800190565b60208082526018908201527f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000604082015260600190565b60208082526038908201527f5374617274696e6720636f756e746572206973206e6f74207175616c20746f2060408201527f696e636f6d696e67206d65737361676520636f756e7465720000000000000000606082015260800190565b60208082526031908201527f4e6f7420656e6f756768207065726d697373696f6e7320746f20726567697374604082015270195c88195e1d1c984818dbdb9d1c9858dd607a1b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526024908201527f44657374696e6174696f6e20636861696e206973206e6f7420696e697469616c6040820152631a5e995960e21b606082015260800190565b60208082526014908201527314185a5c9a5b99c818da1958dac819985a5b195960621b604082015260600190565b602080825260149082015273283ab13634b19025b2bc903737ba1034b710239960611b604082015260600190565b60208082526018908201527f436861696e206973206e6f7420696e697469616c697a65640000000000000000604082015260600190565b6020808252600e908201526d5369676e206e6f7420696e20473160901b604082015260600190565b60208082526019908201527f44454255474745525f524f4c4520697320726571756972656400000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b60208082526024908201527f457874726120636f6e747261637420697320616c726561647920726567697374604082015263195c995960e21b606082015260800190565b60208082526029908201527f4e657720636861696e20686173682063616e6e6f7420626520657175616c20746040820152681bc813585a5b9b995d60ba1b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b92835260208301919091521515604082015260600190565b6000808335601e198436030181126133a6578283fd5b83018035915067ffffffffffffffff8211156133c0578283fd5b6020019150368190038213156125b957600080fd5b60008235605e19833603018112612af6578182fd5b60405181810167ffffffffffffffff8111828210171561340957600080fd5b604052919050565b60005b8381101561342c578181015183820152602001613414565b8381111561343b576000848401525b50505050565b60e01c90565b600060443d101561345757611461565b600481823e6308c379a061346b8251613441565b1461347557611461565b6040513d600319016004823e80513d67ffffffffffffffff81602484011181841117156134a55750505050611461565b828401925082519150808211156134bf5750505050611461565b503d830160208284010111156134d757505050611461565b601f01601f1916810160200160405291505090565b6001600160a01b0381168114611b2357600080fdfe6155b5aac15ce9aa193c0527a6f43be0a36a7e2e7496c2b615c0e5f92284277344657374696e6174696f6e20636f6e7472616374206973206e6f74207265676973746572656430644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47c8cc8bda7ad4886bea3ebbdafa02e79d37c39bf4011696b26a31a0802fd9458ba2646970667358221220093c2d278aeb4ed3411e26a3f398981ce473e254dc3a9b827a467e2847a66c6d64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/Precompiled.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/Precompiled.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/Precompiled.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/Precompiled.json b/predeployed/build/lib/ima_predeployed/artifacts/Precompiled.json new file mode 100644 index 000000000..d407289d1 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/Precompiled.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "Precompiled", + "sourceName": "contracts/schain/bls/Precompiled.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208fbc5f13d907ef5950d0968cfda0ab45322433a917c3e22da0c4fded49c88c4b64736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208fbc5f13d907ef5950d0968cfda0ab45322433a917c3e22da0c4fded49c88c4b64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/ProxyAdmin.json b/predeployed/build/lib/ima_predeployed/artifacts/ProxyAdmin.json new file mode 100644 index 000000000..5d642059a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/ProxyAdmin.json @@ -0,0 +1,160 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ProxyAdmin", + "sourceName": "contracts/proxy/ProxyAdmin.sol", + "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 AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "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": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b61087b8061007d6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461013657806399a88ec4146101f5578063f2fde38b14610230578063f3b7dead146102635761007b565b8063204e1c7a14610080578063715018a6146100cf5780637eff275e146100e65780638da5cb5b14610121575b600080fd5b34801561008c57600080fd5b506100b3600480360360208110156100a357600080fd5b50356001600160a01b0316610296565b604080516001600160a01b039092168252519081900360200190f35b3480156100db57600080fd5b506100e4610328565b005b3480156100f257600080fd5b506100e46004803603604081101561010957600080fd5b506001600160a01b03813581169160200135166103d4565b34801561012d57600080fd5b506100b36104a1565b6100e46004803603606081101561014c57600080fd5b6001600160a01b03823581169260208101359091169181019060608101604082013564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506104b0945050505050565b34801561020157600080fd5b506100e46004803603604081101561021857600080fd5b506001600160a01b03813581169160200135166105e9565b34801561023c57600080fd5b506100e46004803603602081101561025357600080fd5b50356001600160a01b031661069a565b34801561026f57600080fd5b506100b36004803603602081101561028657600080fd5b50356001600160a01b031661079c565b6000806060836001600160a01b03166040518080635c60da1b60e01b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b606091505b50915091508161030957600080fd5b80806020019051602081101561031e57600080fd5b5051949350505050565b6103306107fb565b6001600160a01b03166103416104a1565b6001600160a01b03161461038a576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6103dc6107fb565b6001600160a01b03166103ed6104a1565b6001600160a01b031614610436576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316638f283970826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b6104b86107fb565b6001600160a01b03166104c96104a1565b6001600160a01b031614610512576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b826001600160a01b0316634f1ef2863484846040518463ffffffff1660e01b815260040180836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561057f578181015183820152602001610567565b50505050905090810190601f1680156105ac5780820380516001836020036101000a031916815260200191505b5093505050506000604051808303818588803b1580156105cb57600080fd5b505af11580156105df573d6000803e3d6000fd5b5050505050505050565b6105f16107fb565b6001600160a01b03166106026104a1565b6001600160a01b03161461064b576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316633659cfe6826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b6106a26107fb565b6001600160a01b03166106b36104a1565b6001600160a01b0316146106fc576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b6001600160a01b0381166107415760405162461bcd60e51b81526004018080602001828103825260268152602001806108006026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806060836001600160a01b031660405180806303e1469160e61b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212203768212fc739b6f5d04031f3515c4811eaf8dd5225cdb7a15a3d7fa534d1ba9364736f6c634300060c0033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461013657806399a88ec4146101f5578063f2fde38b14610230578063f3b7dead146102635761007b565b8063204e1c7a14610080578063715018a6146100cf5780637eff275e146100e65780638da5cb5b14610121575b600080fd5b34801561008c57600080fd5b506100b3600480360360208110156100a357600080fd5b50356001600160a01b0316610296565b604080516001600160a01b039092168252519081900360200190f35b3480156100db57600080fd5b506100e4610328565b005b3480156100f257600080fd5b506100e46004803603604081101561010957600080fd5b506001600160a01b03813581169160200135166103d4565b34801561012d57600080fd5b506100b36104a1565b6100e46004803603606081101561014c57600080fd5b6001600160a01b03823581169260208101359091169181019060608101604082013564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506104b0945050505050565b34801561020157600080fd5b506100e46004803603604081101561021857600080fd5b506001600160a01b03813581169160200135166105e9565b34801561023c57600080fd5b506100e46004803603602081101561025357600080fd5b50356001600160a01b031661069a565b34801561026f57600080fd5b506100b36004803603602081101561028657600080fd5b50356001600160a01b031661079c565b6000806060836001600160a01b03166040518080635c60da1b60e01b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b606091505b50915091508161030957600080fd5b80806020019051602081101561031e57600080fd5b5051949350505050565b6103306107fb565b6001600160a01b03166103416104a1565b6001600160a01b03161461038a576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6103dc6107fb565b6001600160a01b03166103ed6104a1565b6001600160a01b031614610436576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316638f283970826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b6104b86107fb565b6001600160a01b03166104c96104a1565b6001600160a01b031614610512576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b826001600160a01b0316634f1ef2863484846040518463ffffffff1660e01b815260040180836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561057f578181015183820152602001610567565b50505050905090810190601f1680156105ac5780820380516001836020036101000a031916815260200191505b5093505050506000604051808303818588803b1580156105cb57600080fd5b505af11580156105df573d6000803e3d6000fd5b5050505050505050565b6105f16107fb565b6001600160a01b03166106026104a1565b6001600160a01b03161461064b576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316633659cfe6826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b6106a26107fb565b6001600160a01b03166106b36104a1565b6001600160a01b0316146106fc576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b6001600160a01b0381166107415760405162461bcd60e51b81526004018080602001828103825260268152602001806108006026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806060836001600160a01b031660405180806303e1469160e61b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212203768212fc739b6f5d04031f3515c4811eaf8dd5225cdb7a15a3d7fa534d1ba9364736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/SkaleVerifier.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/SkaleVerifier.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/SkaleVerifier.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/SkaleVerifier.json b/predeployed/build/lib/ima_predeployed/artifacts/SkaleVerifier.json new file mode 100644 index 000000000..665660707 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/SkaleVerifier.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "SkaleVerifier", + "sourceName": "contracts/schain/bls/SkaleVerifier.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a9431b36756d95801dab0d23c28055d28c6fa6ee04daf2ade85bf5d5ae5a13c364736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a9431b36756d95801dab0d23c28055d28c6fa6ee04daf2ade85bf5d5ae5a13c364736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManager.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManager.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManager.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManager.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManager.json new file mode 100644 index 000000000..d3696529b --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManager.json @@ -0,0 +1,527 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManager", + "sourceName": "contracts/schain/TokenManager.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract CommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract MessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract TokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC1155.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC1155.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC1155.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC1155.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC1155.json new file mode 100644 index 000000000..e8434e21a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC1155.json @@ -0,0 +1,788 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerERC1155", + "sourceName": "contracts/schain/TokenManagers/TokenManagerERC1155.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnSchain", + "type": "address" + } + ], + "name": "ERC1155TokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnSchain", + "type": "address" + } + ], + "name": "ERC1155TokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnSchain", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "ERC1155TokenReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "internalType": "contract ERC1155OnChain", + "name": "erc1155OnSchain", + "type": "address" + } + ], + "name": "addERC1155TokenByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "clonesErc1155", + "outputs": [ + { + "internalType": "contract ERC1155OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract CommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exitToMainERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "exitToMainERC1155Batch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract MessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract TokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferToSchainERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "transferToSchainERC1155Batch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b506170e6806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620002385760003560e01c80636d6112861162000135578063b9581c5011620000bd578063cc5b715b1162000087578063cc5b715b1462000490578063d547741f146200049a578063dec2deb614620004b1578063e7ece22814620004bb578063edcc12b514620004d25762000238565b8063b9581c501462000441578063c0e312dc146200044b578063ca15c8731462000462578063cb703bff14620004795762000238565b806391d1485411620000ff57806391d1485414620003f2578063a217fddf1462000409578063ade686761462000413578063b626a44f146200042a5762000238565b80636d61128614620003b05780636d6c68e614620003ba578063884cee5a14620003c45780639010d07c14620003db5762000238565b806336568abe11620001c557806350f44280116200018f57806350f4428014620003485780635492d3b514620003615780635573b8b614620003785780636685bde514620003825780636ce681d214620003995762000238565b806336568abe14620002f757806339927cf9146200030e5780633b690b6b14620003345780633fa194ce146200033e5762000238565b8063248a9ca31162000207578063248a9ca314620002a657806328c5e18214620002cc5780632dc151de14620002d65780632f2ff15d14620002e05762000238565b8063029996b8146200023d578063066ee47f14620002495780630b885ac314620002605780630f1a8f741462000277575b600080fd5b62000247620004e9565b005b620002476200025a36600462002b0a565b62000541565b620002476200027136600462002c48565b6200081c565b6200028e620002883660046200298e565b620008bc565b6040516200029d919062002ee3565b60405180910390f35b620002bd620002b73660046200298e565b620008d7565b6040516200029d919062003036565b620002bd620008ec565b6200028e62000937565b62000247620002f1366004620029a7565b62000946565b6200024762000308366004620029a7565b62000996565b620003256200031f36600462002a6d565b620009df565b6040516200029d91906200302b565b620002bd62000a3e565b620002bd62000a44565b6200035262000a57565b6040516200029d919062003099565b620002476200037236600462002bc9565b62000a7a565b6200028e62000cc9565b6200028e6200039336600462002836565b62000cd8565b62000247620003aa36600462002c48565b62000cf3565b6200028e62000e59565b6200028e62000e68565b62000325620003d5366004620029ce565b62000e77565b6200028e620003ec36600462002a2d565b62001008565b6200032562000403366004620029a7565b62001029565b620002bd62001043565b620002476200042436600462002855565b62001048565b620002476200043b3660046200292f565b620012cd565b62000247620013a2565b620002476200045c36600462002a6d565b620013eb565b620002bd620004733660046200298e565b620014b3565b620002476200048a36600462002ab0565b620014cc565b620002bd620015ce565b62000247620004ab366004620029a7565b620015f2565b6200032562001632565b62000247620004cc366004620028e5565b62001642565b62000247620004e336600462002836565b62001835565b62000504600080516020620070918339815191523362001029565b6200052c5760405162461bcd60e51b815260040162000523906200338c565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b6001600160a01b0383166200056a5760405162461bcd60e51b815260040162000523906200350e565b600086866040516020016200058192919062002eb5565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b848301529151919350620005c392910162002ec5565b60405160208183030381529060405280519060200120811415620005fb5760405162461bcd60e51b8152600401620005239062003271565b6000818152606a60205260409020546001600160a01b0316620006325760405162461bcd60e51b81526004016200052390620030e6565b6001600160a01b038086166000908152606b602052604090205416620006588162001883565b620006775760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c590620006a7903390309060040162002ef7565b60206040518083038186803b158015620006c057600080fd5b505afa158015620006d5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006fb91906200296c565b6200071a5760405162461bcd60e51b81526004016200052390620033cd565b604051631ac8311560e21b81526001600160a01b03821690636b20c454906200074c9033908890889060040162002f11565b600060405180830381600087803b1580156200076757600080fd5b505af11580156200077c573d6000803e3d6000fd5b505050506060620007908787878762001889565b6065546000858152606a6020526040908190205490516365e3781f60e01b81529293506001600160a01b03918216926365e3781f92620007dd928e928e929091169087906004016200303f565b600060405180830381600087803b158015620007f857600080fd5b505af11580156200080d573d6000803e3d6000fd5b50505050505050505050505050565b600054610100900460ff16806200083857506200083862001907565b8062000847575060005460ff16155b620008665760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562000892576000805460ff1961ff0019909116610100171660011790555b620008a1868686868662000cf3565b8015620008b4576000805461ff00191690555b505050505050565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200091e919062002ec5565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b6000828152603360205260409020600201546200096790620004036200191a565b620009865760405162461bcd60e51b815260040162000523906200315f565b6200099282826200191e565b5050565b620009a06200191a565b6001600160a01b0316816001600160a01b031614620009d35760405162461bcd60e51b8152600401620005239062003699565b6200099282826200198c565b6000806001600160a01b0316606a6000858560405160200162000a0492919062002eb5565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b60685481565b6000805160206200709183398151915281565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6001600160a01b03831662000aa35760405162461bcd60e51b815260040162000523906200350e565b6000868660405160200162000aba92919062002eb5565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000afc92910162002ec5565b6040516020818303038152906040528051906020012081141562000b345760405162461bcd60e51b8152600401620005239062003271565b6000818152606a60205260409020546001600160a01b031662000b6b5760405162461bcd60e51b81526004016200052390620030e6565b6001600160a01b038086166000908152606b60205260409020541662000b918162001883565b62000bb05760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c59062000be0903390309060040162002ef7565b60206040518083038186803b15801562000bf957600080fd5b505afa15801562000c0e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c3491906200296c565b62000c535760405162461bcd60e51b81526004016200052390620033cd565b604051637a94c56560e11b81526001600160a01b0382169063f5298aca9062000c859033908890889060040162002f55565b600060405180830381600087803b15801562000ca057600080fd5b505af115801562000cb5573d6000803e3d6000fd5b5050505060606200079087878787620019fa565b6065546001600160a01b031681565b606b602052600090815260409020546001600160a01b031681565b600054610100900460ff168062000d0f575062000d0f62001907565b8062000d1e575060005460ff16155b62000d3d5760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562000d69576000805460ff1961ff0019909116610100171660011790555b62000d7362001a5e565b62000d8060003362000986565b62000d9b600080516020620070918339815191523362000986565b62000dc77ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362000986565b8560405160200162000dda919062002ec5565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b031992831617909255606680548784169083161790556067805486841690831617905560698054928516929091169190911790558015620008b4576000805461ff0019169055505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b6065546000906001600160a01b0316331462000ea75760405162461bcd60e51b81526004016200052390620031ae565b606854851415801562000f3957506040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000ee7919062002ec5565b60405160208183030381529060405280519060200120851462000f27576000858152606a60205260409020546001600160a01b0385811691161462000f39565b6069546001600160a01b038581169116145b62000f585760405162461bcd60e51b815260040162000523906200357c565b600062000f66848462001afe565b9050600981600c81111562000f7757fe5b148062000f905750600a81600c81111562000f8e57fe5b145b1562000fa85762000fa2848462001b49565b62000ffc565b600b81600c81111562000fb757fe5b148062000fd05750600c81600c81111562000fce57fe5b145b1562000fe25762000fa2848462001dec565b60405162461bcd60e51b81526004016200052390620036e8565b50600195945050505050565b60008281526033602052604081206200102290836200206a565b9392505050565b600082815260336020526040812062001022908362002078565b600081565b6001600160a01b038316620010715760405162461bcd60e51b815260040162000523906200350e565b6001600160a01b038085166000908152606b6020526040908190205460675491516311be333d60e11b815290831692919091169063237c667a90620010bb90879060040162002ee3565b600060405180830381600087803b158015620010d657600080fd5b505af1158015620010eb573d6000803e3d6000fd5b5050505062001103816001600160a01b031662001883565b620011225760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c59062001152903390309060040162002ef7565b60206040518083038186803b1580156200116b57600080fd5b505afa15801562001180573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011a691906200296c565b620011c55760405162461bcd60e51b81526004016200052390620033cd565b604051631ac8311560e21b81526001600160a01b03821690636b20c45490620011f79033908790879060040162002f11565b600060405180830381600087803b1580156200121257600080fd5b505af115801562001227573d6000803e3d6000fd5b5050505060606200123b8686868662001889565b606554604080518082018252600781526613585a5b9b995d60ca1b602082015260695491516365e3781f60e01b81529394506001600160a01b03928316936365e3781f93620012919316908690600401620030ae565b600060405180830381600087803b158015620012ac57600080fd5b505af1158015620012c1573d6000803e3d6000fd5b50505050505050505050565b620012f97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001029565b620013185760405162461bcd60e51b8152600401620005239062003454565b6200132c816001600160a01b031662001883565b6200134b5760405162461bcd60e51b8152600401620005239062003545565b6001600160a01b038281166000818152606b602052604080822080546001600160a01b0319169486169485179055517f096b3e2c36bc263e90f7577e70dc47b6536fc8d85d467d54f61f91c2ca091c519190a35050565b620013bd600080516020620070918339815191523362001029565b620013dc5760405162461bcd60e51b815260040162000523906200338c565b6069805460ff60a01b19169055565b6066546001600160a01b03163314806200140d57506200140d60003362001029565b6200142c5760405162461bcd60e51b8152600401620005239062003633565b600082826040516020016200144392919062002eb5565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b0316620014935760405162461bcd60e51b81526004016200052390620032c1565b6000908152606a6020526040902080546001600160a01b03191690555050565b600081815260336020526040812062000a38906200208f565b6066546001600160a01b0316331480620014ee5750620014ee60003362001029565b6200150d5760405162461bcd60e51b8152600401620005239062003633565b600083836040516020016200152492919062002eb5565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031615620015755760405162461bcd60e51b81526004016200052390620035fc565b6001600160a01b0382166200159e5760405162461bcd60e51b81526004016200052390620030e6565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b6000828152603360205260409020600201546200161390620004036200191a565b620009d35760405162461bcd60e51b8152600401620005239062003404565b606954600160a01b900460ff1681565b6001600160a01b0383166200166b5760405162461bcd60e51b815260040162000523906200350e565b6001600160a01b038085166000908152606b6020526040908190205460675491516311be333d60e11b815290831692919091169063237c667a90620016b590879060040162002ee3565b600060405180830381600087803b158015620016d057600080fd5b505af1158015620016e5573d6000803e3d6000fd5b50505050620016fd816001600160a01b031662001883565b6200171c5760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c5906200174c903390309060040162002ef7565b60206040518083038186803b1580156200176557600080fd5b505afa1580156200177a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017a091906200296c565b620017bf5760405162461bcd60e51b81526004016200052390620033cd565b604051637a94c56560e11b81526001600160a01b0382169063f5298aca90620017f19033908790879060040162002f55565b600060405180830381600087803b1580156200180c57600080fd5b505af115801562001821573d6000803e3d6000fd5b5050505060606200123b86868686620019fa565b6200184260003362001029565b620018615760405162461bcd60e51b815260040162000523906200323a565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b3b151590565b6060620018956200245e565b6040805160c081019091528060a0810180600b8152508152602001876001600160a01b03168152602001866001600160a01b0316815260200185815260200184815250905080604051602001620018ed919062003718565b604051602081830303815290604052915050949350505050565b6000620019143062001883565b15905090565b3390565b60008281526033602052604090206200193890826200209c565b156200099257620019486200191a565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020620019a69082620020b3565b156200099257620019b66200191a565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b606062001a0662002494565b6040805160c081019091528060a081018060098152508152602001876001600160a01b03168152602001866001600160a01b0316815260200185815260200184815250905080604051602001620018ed91906200378c565b600054610100900460ff168062001a7a575062001a7a62001907565b8062001a89575060005460ff16155b62001aa85760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562001ad4576000805460ff1961ff0019909116610100171660011790555b62001ade620020ca565b62001ae8620020ca565b801562001afb576000805461ff00191690555b50565b60008062001b0f838501856200298e565b90506020810662001b3b5762001b3262001b2c8483818862003804565b62001afe565b91505062000a38565b62001b328385018562002a4f565b600062001b57838362001afe565b90506000808080600985600c81111562001b6d57fe5b141562001baf5762001b7e62002494565b62001b8a888862002154565b9050806040015194508060200151935080606001519250806080015191505062001cd4565b62001bb9620024cb565b62001bc58888620021a6565b805160408082015160208084015160608501516080909501516001600160a01b038083166000908152606b9094529490922054929a509850929650919450919250168062001cd157606954600160a01b900460ff1662001c395760405162461bcd60e51b81526004016200052390620034d7565b60208201515160405162001c4d90620024f4565b62001c59919062003099565b604051809103906000f08015801562001c76573d6000803e3d6000fd5b506001600160a01b038681166000818152606b602052604080822080546001600160a01b031916948616948517905551939450919290917ff591ef422bd6af456a3cad967032f043099a7d9838494d88ba15d16a89f50b7491a35b50505b6001600160a01b038084166000908152606b60205260409020541662001cfa8162001883565b62001d195760405162461bcd60e51b8152600401620005239062003545565b60405163731133e960e01b81526001600160a01b0382169063731133e99062001d4b9088908790879060040162002fc9565b600060405180830381600087803b15801562001d6657600080fd5b505af115801562001d7b573d6000803e3d6000fd5b50505050806001600160a01b0316846001600160a01b03167f84899afd4ab55115c2eab5a59471e73bc42359e7c3d4e5a3c1aa4837bd20ed5562001dbf86620021f8565b62001dca86620021f8565b60405162001dda92919062002ff9565b60405180910390a35050505050505050565b600062001dfa838362001afe565b9050600080606080600b85600c81111562001e1157fe5b141562001e535762001e226200245e565b62001e2e88886200223a565b9050806040015194508060200151935080606001519250806080015191505062001f78565b62001e5d62002502565b62001e6988886200228c565b805160408082015160208084015160608501516080909501516001600160a01b038083166000908152606b9094529490922054929a509850929650919450919250168062001f7557606954600160a01b900460ff1662001edd5760405162461bcd60e51b81526004016200052390620034d7565b60208201515160405162001ef190620024f4565b62001efd919062003099565b604051809103906000f08015801562001f1a573d6000803e3d6000fd5b506001600160a01b038681166000818152606b602052604080822080546001600160a01b031916948616948517905551939450919290917ff591ef422bd6af456a3cad967032f043099a7d9838494d88ba15d16a89f50b7491a35b50505b6001600160a01b038084166000908152606b60205260409020541662001f9e8162001883565b62001fbd5760405162461bcd60e51b8152600401620005239062003545565b604051630fbfeffd60e11b81526001600160a01b03821690631f7fdffa9062001fef9088908790879060040162002f76565b600060405180830381600087803b1580156200200a57600080fd5b505af11580156200201f573d6000803e3d6000fd5b50505050806001600160a01b0316846001600160a01b03167f84899afd4ab55115c2eab5a59471e73bc42359e7c3d4e5a3c1aa4837bd20ed55858560405162001dda92919062002ff9565b6000620010228383620022de565b600062001022836001600160a01b03841662002327565b600062000a38826200233f565b600062001022836001600160a01b03841662002343565b600062001022836001600160a01b03841662002392565b600054610100900460ff1680620020e65750620020e662001907565b80620020f5575060005460ff16155b620021145760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562001ae8576000805460ff1961ff001990911661010017166001179055801562001afb576000805461ff001916905550565b6200215e62002494565b60096200216c848462001afe565b600c8111156200217857fe5b14620021985760405162461bcd60e51b81526004016200052390620032f8565b620010228284018462002e1a565b620021b0620024cb565b600a620021be848462001afe565b600c811115620021ca57fe5b14620021ea5760405162461bcd60e51b815260040162000523906200333c565b620010228284018462002cdb565b6040805160018082528183019092526060916020808301908036833701905050905081816000815181106200222957fe5b602002602001018181525050919050565b620022446200245e565b600b62002252848462001afe565b600c8111156200225e57fe5b146200227e5760405162461bcd60e51b81526004016200052390620035b3565b620010228284018462002ddc565b6200229662002502565b600c620022a4848462001afe565b600c811115620022b057fe5b14620022d05760405162461bcd60e51b81526004016200052390620031e5565b620010228284018462002d61565b81546000908210620023045760405162461bcd60e51b815260040162000523906200311d565b8260000182815481106200231457fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b600062002351838362002327565b620023895750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000a38565b50600062000a38565b60008181526001830160205260408120548015620024535783546000198083019190810190600090879083908110620023c757fe5b9060005260206000200154905080876000018481548110620023e557fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806200241657fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505062000a38565b600091505062000a38565b6040518060a001604052806200247362002517565b81526000602082018190526040820152606080820181905260809091015290565b6040518060a00160405280620024a962002517565b8152600060208201819052604082018190526060820181905260809091015290565b6040518060400160405280620024e062002494565b8152602001620024ef6200252b565b905290565b613819806200387883390190565b6040518060400160405280620024e06200245e565b6040805160208101909152806000620024ef565b6040518060200160405280606081525090565b600082601f8301126200254f578081fd5b81356001600160401b0381111562002565578182fd5b602080820262002577828201620037dd565b838152935081840185830182870184018810156200259457600080fd5b600092505b84831015620025b957803582526001929092019190830190830162002599565b505050505092915050565b60008083601f840112620025d6578182fd5b5081356001600160401b03811115620025ed578182fd5b6020830191508360208285010111156200260657600080fd5b9250929050565b8035600d811062000a3857600080fd5b600082601f8301126200262e578081fd5b81356001600160401b0381111562002644578182fd5b62002659601f8201601f1916602001620037dd565b91508082528360208285010111156200267157600080fd5b8060208401602084013760009082016020015292915050565b6000602082840312156200269c578081fd5b620026a86020620037dd565b9050620026b683836200260d565b815292915050565b600060208284031215620026d0578081fd5b620026dc6020620037dd565b905081356001600160401b03811115620026f557600080fd5b62002703848285016200261d565b82525092915050565b600060a082840312156200271e578081fd5b6200272a60a0620037dd565b90506200273883836200268a565b815260208201356200274a8162003861565b602082015260408201356200275f8162003861565b604082015260608201356001600160401b03808211156200277f57600080fd5b6200278d858386016200253e565b60608401526080840135915080821115620027a757600080fd5b50620027b6848285016200253e565b60808301525092915050565b600060a08284031215620027d4578081fd5b620027e060a0620037dd565b9050620027ee83836200268a565b81526020820135620028008162003861565b60208201526040820135620028158162003861565b80604083015250606082013560608201526080820135608082015292915050565b60006020828403121562002848578081fd5b8135620010228162003861565b600080600080608085870312156200286b578283fd5b8435620028788162003861565b935060208501356200288a8162003861565b925060408501356001600160401b0380821115620028a6578384fd5b620028b4888389016200253e565b93506060870135915080821115620028ca578283fd5b50620028d9878288016200253e565b91505092959194509250565b60008060008060808587031215620028fb578384fd5b8435620029088162003861565b935060208501356200291a8162003861565b93969395505050506040820135916060013590565b6000806040838503121562002942578182fd5b82356200294f8162003861565b91506020830135620029618162003861565b809150509250929050565b6000602082840312156200297e578081fd5b8151801515811462001022578182fd5b600060208284031215620029a0578081fd5b5035919050565b60008060408385031215620029ba578182fd5b823591506020830135620029618162003861565b60008060008060608587031215620029e4578182fd5b843593506020850135620029f88162003861565b925060408501356001600160401b0381111562002a13578283fd5b62002a2187828801620025c4565b95989497509550505050565b6000806040838503121562002a40578182fd5b50508035926020909101359150565b60006020828403121562002a61578081fd5b6200102283836200260d565b6000806020838503121562002a80578182fd5b82356001600160401b0381111562002a96578283fd5b62002aa485828601620025c4565b90969095509350505050565b60008060006040848603121562002ac5578081fd5b83356001600160401b0381111562002adb578182fd5b62002ae986828701620025c4565b909450925050602084013562002aff8162003861565b809150509250925092565b60008060008060008060a0878903121562002b23578384fd5b86356001600160401b038082111562002b3a578586fd5b62002b488a838b01620025c4565b90985096506020890135915062002b5f8262003861565b90945060408801359062002b738262003861565b9093506060880135908082111562002b89578384fd5b62002b978a838b016200253e565b9350608089013591508082111562002bad578283fd5b5062002bbc89828a016200253e565b9150509295509295509295565b60008060008060008060a0878903121562002be2578384fd5b86356001600160401b0381111562002bf8578485fd5b62002c0689828a01620025c4565b909750955050602087013562002c1c8162003861565b9350604087013562002c2e8162003861565b959894975092956060810135946080909101359350915050565b600080600080600060a0868803121562002c60578283fd5b85356001600160401b0381111562002c76578384fd5b62002c84888289016200261d565b955050602086013562002c978162003861565b9350604086013562002ca98162003861565b9250606086013562002cbb8162003861565b9150608086013562002ccd8162003861565b809150509295509295909350565b60006020828403121562002ced578081fd5b81356001600160401b038082111562002d04578283fd5b9083019060c0828603121562002d18578283fd5b62002d246040620037dd565b62002d308684620027c2565b815260a08301358281111562002d44578485fd5b62002d5287828601620026be565b60208301525095945050505050565b60006020828403121562002d73578081fd5b81356001600160401b038082111562002d8a578283fd5b908301906040828603121562002d9e578283fd5b62002daa6040620037dd565b82358281111562002db9578485fd5b62002dc7878286016200270c565b82525060208301358281111562002d44578485fd5b60006020828403121562002dee578081fd5b81356001600160401b0381111562002e04578182fd5b62002e12848285016200270c565b949350505050565b600060a0828403121562002e2c578081fd5b620010228383620027c2565b6000815180845260208085019450808401835b8381101562002e695781518752958201959082019060010162002e4b565b509495945050505050565b6000815180845262002e8e8160208601602086016200382e565b601f01601f19169290920160200192915050565b8051600d811062002eaf57fe5b90915250565b6000828483379101908152919050565b6000825162002ed98184602087016200382e565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b038416815260606020820181905260009062002f379083018562002e38565b828103604084015262002f4b818562002e38565b9695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b038416815260806020820181905260009062002f9c9083018562002e38565b828103604084015262002fb0818562002e38565b8381036060909401939093525081526020019392505050565b6001600160a01b039390931683526020830191909152604082015260806060820181905260009082015260a00190565b6000604082526200300e604083018562002e38565b828103602084015262003022818562002e38565b95945050505050565b901515815260200190565b90815260200190565b60006060825284606083015284866080840137608085830181018290526001600160a01b0385166020840152601f8601601f1916830183810382016040850152906200308e9082018562002e74565b979650505050505050565b60006020825262001022602083018462002e74565b600060608252620030c3606083018662002e74565b6001600160a01b0385166020840152828103604084015262002f4b818562002e74565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b60208082526035908201527f4d6573736167652074797065206973206e6f742045524331313535426174636860408201527420b7322a37b5b2b724b73337903a3930b739b332b960591b606082015260800190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526024908201527f4d6573736167652074797065206973206e6f742045524331313535207472616e60408201526339b332b960e11b606082015260800190565b60208082526030908201527f4d6573736167652074797065206973206e6f742045524331313535416e64546f60408201526f35b2b724b73337903a3930b739b332b960811b606082015260800190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60208082526019908201527f4e6f7420616c6c6f776564204552433131353520546f6b656e00000000000000604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601c908201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604082015260600190565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b60208082526029908201527f4d6573736167652074797065206973206e6f7420455243313135354261746368604082015268103a3930b739b332b960b91b606082015260800190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b60208082526018908201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60208082526016908201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604082015260600190565b6000602082526200372e60208301845162002ea2565b60208301516001600160a01b039081166040848101919091528401511660608084019190915283015160a060808401526200376d60c084018262002e38565b90506080840151601f198483030160a085015262003022828262002e38565b600060a082019050620037a182845162002ea2565b602083015160018060a01b0380821660208501528060408601511660408501525050606083015160608301526080830151608083015292915050565b6040518181016001600160401b0381118282101715620037fc57600080fd5b604052919050565b6000808585111562003814578182fd5b8386111562003821578182fd5b5050820193919092039150565b60005b838110156200384b57818101518382015260200162003831565b838111156200385b576000848401525b50505050565b6001600160a01b038116811462001afb57600080fdfe60806040523480156200001157600080fd5b506040516200381938038062003819833981810160405260208110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052505050620001026200017360201b620017601760201c565b62000118816200023160201b620018121760201c565b6200012d620002fb60201b620018cd1760201c565b62000148600080516020620037f983398151915280620003a3565b6200016c600080516020620037f983398151915262000166620003f5565b620003f9565b5062000872565b600054610100900460ff16806200018f57506200018f62000405565b806200019e575060005460ff16155b620001db5760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff1615801562000207576000805460ff1961ff0019909116610100171660011790555b6200021162000423565b6200021b62000423565b80156200022e576000805461ff00191690555b50565b600054610100900460ff16806200024d57506200024d62000405565b806200025c575060005460ff16155b620002995760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff16158015620002c5576000805460ff1961ff0019909116610100171660011790555b620002cf62000423565b620002d9620004cb565b620002e48262000571565b8015620002f7576000805461ff00191690555b5050565b600054610100900460ff16806200031757506200031762000405565b8062000326575060005460ff16155b620003635760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200038f576000805460ff1961ff0019909116610100171660011790555b6200039962000423565b62000211620004cb565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620002f7828262000634565b60006200041d30620006af60201b6200196a1760201c565b15905090565b600054610100900460ff16806200043f57506200043f62000405565b806200044e575060005460ff16155b6200048b5760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200021b576000805460ff1961ff00199091166101001716600117905580156200022e576000805461ff001916905550565b600054610100900460ff1680620004e75750620004e762000405565b80620004f6575060005460ff16155b620005335760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200055f576000805460ff1961ff0019909116610100171660011790555b6200021b6301ffc9a760e01b620006b5565b600054610100900460ff16806200058d57506200058d62000405565b806200059c575060005460ff16155b620005d95760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff1615801562000605576000805460ff1961ff0019909116610100171660011790555b62000610826200073a565b62000622636cdb3d1360e11b620006b5565b620002e46303a24d0760e21b620006b5565b60008281526033602090815260409091206200065b918390620019706200074f821b17901c565b15620002f7576200066b620003f5565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b6001600160e01b0319808216141562000715576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b8051620002f7906099906020840190620007d6565b600062000766836001600160a01b0384166200076f565b90505b92915050565b60006200077d8383620007be565b620007b55750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000769565b50600062000769565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200081957805160ff191683800117855562000849565b8280016001018555821562000849579182015b82811115620008495782518255916020019190600101906200082c565b50620008579291506200085b565b5090565b5b808211156200085757600081556001016200085c565b612f4980620008826000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c87314610a3d578063d539139314610a5a578063d547741f14610a62578063e985e9c514610a8e578063f242432a14610abc578063f5298aca14610b8557610136565b8063731133e9146108dc5780639010d07c1461099c57806391d14854146109db578063a217fddf14610a07578063a22cb46514610a0f57610136565b80632eb2c2d6116100ff5780632eb2c2d61461041d5780632f2ff15d146105de57806336568abe1461060a5780634e1273f4146106365780636b20c454146107a957610136565b8062fdd58e1461013b57806301ffc9a7146101795780630e89341c146101b45780631f7fdffa14610246578063248a9ca314610400575b600080fd5b6101676004803603604081101561015157600080fd5b506001600160a01b038135169060200135610bb7565b60408051918252519081900360200190f35b6101a06004803603602081101561018f57600080fd5b50356001600160e01b031916610c29565b604080519115158252519081900360200190f35b6101d1600480360360208110156101ca57600080fd5b5035610c48565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103fe6004803603608081101561025c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561028657600080fd5b82018360208201111561029857600080fd5b803590602001918460208302840111600160201b831117156102b957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561030857600080fd5b82018360208201111561031a57600080fd5b803590602001918460208302840111600160201b8311171561033b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561038a57600080fd5b82018360208201111561039c57600080fd5b803590602001918460018302840111600160201b831117156103bd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ce0945050505050565b005b6101676004803603602081101561041657600080fd5b5035610d6d565b6103fe600480360360a081101561043357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561046657600080fd5b82018360208201111561047857600080fd5b803590602001918460208302840111600160201b8311171561049957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156104e857600080fd5b8201836020820111156104fa57600080fd5b803590602001918460208302840111600160201b8311171561051b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561056a57600080fd5b82018360208201111561057c57600080fd5b803590602001918460018302840111600160201b8311171561059d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610d82945050505050565b6103fe600480360360408110156105f457600080fd5b50803590602001356001600160a01b0316611085565b6103fe6004803603604081101561062057600080fd5b50803590602001356001600160a01b03166110ec565b6107596004803603604081101561064c57600080fd5b810190602081018135600160201b81111561066657600080fd5b82018360208201111561067857600080fd5b803590602001918460208302840111600160201b8311171561069957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156106e857600080fd5b8201836020820111156106fa57600080fd5b803590602001918460208302840111600160201b8311171561071b57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061114d945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561079557818101518382015260200161077d565b505050509050019250505060405180910390f35b6103fe600480360360608110156107bf57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156107e957600080fd5b8201836020820111156107fb57600080fd5b803590602001918460208302840111600160201b8311171561081c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561086b57600080fd5b82018360208201111561087d57600080fd5b803590602001918460208302840111600160201b8311171561089e57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611239945050505050565b6103fe600480360360808110156108f257600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561092857600080fd5b82018360208201111561093a57600080fd5b803590602001918460018302840111600160201b8311171561095b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506112b2945050505050565b6109bf600480360360408110156109b257600080fd5b5080359060200135611334565b604080516001600160a01b039092168252519081900360200190f35b6101a0600480360360408110156109f157600080fd5b50803590602001356001600160a01b0316611353565b61016761136b565b6103fe60048036036040811015610a2557600080fd5b506001600160a01b0381351690602001351515611370565b61016760048036036020811015610a5357600080fd5b503561145f565b610167611476565b6103fe60048036036040811015610a7857600080fd5b50803590602001356001600160a01b031661149a565b6101a060048036036040811015610aa457600080fd5b506001600160a01b03813581169160200135166114f3565b6103fe600480360360a0811015610ad257600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610b1157600080fd5b820183602082011115610b2357600080fd5b803590602001918460018302840111600160201b83111715610b4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611521945050505050565b6103fe60048036036060811015610b9b57600080fd5b506001600160a01b0381351690602081013590604001356116ec565b60006001600160a01b038316610bfe5760405162461bcd60e51b815260040180806020018281038252602b815260200180612cd0602b913960400191505060405180910390fd5b5060008181526097602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526065602052604090205460ff1690565b60998054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610cd45780601f10610ca957610100808354040283529160200191610cd4565b820191906000526020600020905b815481529060010190602001808311610cb757829003601f168201915b50505050509050919050565b610d117f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611353565b610d5b576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461198a565b50505050565b60009081526033602052604090206002015490565b8151835114610dc25760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6001600160a01b038416610e075760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b610e0f611985565b6001600160a01b0316856001600160a01b03161480610e3a5750610e3a85610e35611985565b6114f3565b610e755760405162461bcd60e51b8152600401808060200182810382526032815260200180612d9d6032913960400191505060405180910390fd5b6000610e7f611985565b9050610e8f81878787878761107d565b60005b8451811015610f95576000858281518110610ea957fe5b602002602001015190506000858381518110610ec157fe5b60200260200101519050610f2e816040518060600160405280602a8152602001612e20602a91396097600086815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b60008381526097602090815260408083206001600160a01b038e811685529252808320939093558a1681522054610f659082611c76565b60009283526097602090815260408085206001600160a01b038c1686529091529092209190915550600101610e92565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561101b578181015183820152602001611003565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561105a578181015183820152602001611042565b5050505090500194505050505060405180910390a461107d818787878787611cd0565b505050505050565b6000828152603360205260409020600201546110a390610d0c611985565b6110de5760405162461bcd60e51b815260040180806020018281038252602f815260200180612ca1602f913960400191505060405180910390fd5b6110e88282611f4f565b5050565b6110f4611985565b6001600160a01b0316816001600160a01b0316146111435760405162461bcd60e51b815260040180806020018281038252602f815260200180612ee5602f913960400191505060405180910390fd5b6110e88282611fb8565b6060815183511461118f5760405162461bcd60e51b8152600401808060200182810382526029815260200180612e736029913960400191505060405180910390fd5b6060835167ffffffffffffffff811180156111a957600080fd5b506040519080825280602002602001820160405280156111d3578160200160208202803683370190505b50905060005b8451811015611231576112128582815181106111f157fe5b602002602001015185838151811061120557fe5b6020026020010151610bb7565b82828151811061121e57fe5b60209081029190910101526001016111d9565b509392505050565b611241611985565b6001600160a01b0316836001600160a01b03161480611267575061126783610e35611985565b6112a25760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612021565b505050565b6112de7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611328576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461228f565b600082815260336020526040812061134c9083612390565b9392505050565b600082815260336020526040812061134c908361239c565b600081565b816001600160a01b0316611382611985565b6001600160a01b031614156113c85760405162461bcd60e51b8152600401808060200182810382526029815260200180612e4a6029913960400191505060405180910390fd5b80609860006113d5611985565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611419611985565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b6000818152603360205260408120610c23906123b1565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6000828152603360205260409020600201546114b890610d0c611985565b6111435760405162461bcd60e51b8152600401808060200182810382526030815260200180612d486030913960400191505060405180910390fd5b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166115665760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b61156e611985565b6001600160a01b0316856001600160a01b03161480611594575061159485610e35611985565b6115cf5760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b60006115d9611985565b90506115f98187876115ea886123bc565b6115f3886123bc565b8761107d565b611640836040518060600160405280602a8152602001612e20602a913960008781526097602090815260408083206001600160a01b038d1684529091529020549190611bdf565b60008581526097602090815260408083206001600160a01b038b811685529252808320939093558716815220546116779084611c76565b60008581526097602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461107d818787878787612400565b6116f4611985565b6001600160a01b0316836001600160a01b0316148061171a575061171a83610e35611985565b6117555760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612571565b600054610100900460ff168061177957506117796126a4565b80611787575060005460ff16155b6117c25760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117ed576000805460ff1961ff0019909116610100171660011790555b6117f56126b5565b6117fd6126b5565b801561180f576000805461ff00191690555b50565b600054610100900460ff168061182b575061182b6126a4565b80611839575060005460ff16155b6118745760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561189f576000805460ff1961ff0019909116610100171660011790555b6118a76126b5565b6118af612755565b6118b8826127f2565b80156110e8576000805461ff00191690555050565b600054610100900460ff16806118e657506118e66126a4565b806118f4575060005460ff16155b61192f5760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561195a576000805460ff1961ff0019909116610100171660011790555b6119626126b5565b6117f5612755565b3b151590565b600061134c836001600160a01b0384166128a8565b335b90565b6001600160a01b0384166119cf5760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b8151835114611a0f5760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6000611a19611985565b9050611a2a8160008787878761107d565b60005b8451811015611aee57611aa560976000878481518110611a4957fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002054858381518110611a8f57fe5b6020026020010151611c7690919063ffffffff16565b60976000878481518110611ab557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101611a2d565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015611b75578181015183820152602001611b5d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015611bb4578181015183820152602001611b9c565b5050505090500194505050505060405180910390a4611bd881600087878787611cd0565b5050505050565b60008184841115611c6e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c33578181015183820152602001611c1b565b50505050905090810190601f168015611c605780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008282018381101561134c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b611ce2846001600160a01b031661196a565b1561107d57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015611d70578181015183820152602001611d58565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015611daf578181015183820152602001611d97565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015611deb578181015183820152602001611dd3565b50505050905090810190601f168015611e185780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b158015611e3d57600080fd5b505af1925050508015611e6257506040513d6020811015611e5d57600080fd5b505160015b611ef757611e6e612b7d565b80611e795750611ec0565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315611c33578181015183820152602001611c1b565b60405162461bcd60e51b8152600401808060200182810382526034815260200180612c236034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b50505050505050565b6000828152603360205260409020611f679082611970565b156110e857611f74611985565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020611fd090826128f2565b156110e857611fdd611985565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b0383166120665760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b80518251146120a65760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b60006120b0611985565b90506120d08185600086866040518060200160405280600081525061107d565b60005b83518110156121ae576121658382815181106120eb57fe5b6020026020010151604051806060016040528060248152602001612cfb602491396097600088868151811061211c57fe5b602002602001015181526020019081526020016000206000896001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b6097600086848151811061217557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038a1682529092529020556001016120d3565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561223557818101518382015260200161221d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561227457818101518382015260200161225c565b5050505090500194505050505060405180910390a450505050565b6001600160a01b0384166122d45760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b60006122de611985565b90506122f0816000876115ea886123bc565b60008481526097602090815260408083206001600160a01b038916845290915290205461231d9084611c76565b60008581526097602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a4611bd881600087878787612400565b600061134c8383612907565b600061134c836001600160a01b03841661296b565b6000610c2382612983565b6040805160018082528183019092526060918291906020808301908036833701905050905082816000815181106123ef57fe5b602090810291909101015292915050565b612412846001600160a01b031661196a565b1561107d57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156124a1578181015183820152602001612489565b50505050905090810190601f1680156124ce5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b1580156124f157600080fd5b505af192505050801561251657506040513d602081101561251157600080fd5b505160015b61252257611e6e612b7d565b6001600160e01b0319811663f23a6e6160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b6001600160a01b0383166125b65760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b60006125c0611985565b90506125f0818560006125d2876123bc565b6125db876123bc565b6040518060200160405280600081525061107d565b61263782604051806060016040528060248152602001612cfb6024913960008681526097602090815260408083206001600160a01b038b1684529091529020549190611bdf565b60008481526097602090815260408083206001600160a01b03808a16808652918452828520959095558151888152928301879052815193949093908616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a450505050565b60006126af3061196a565b15905090565b600054610100900460ff16806126ce57506126ce6126a4565b806126dc575060005460ff16155b6127175760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117fd576000805460ff1961ff001990911661010017166001179055801561180f576000805461ff001916905550565b600054610100900460ff168061276e575061276e6126a4565b8061277c575060005460ff16155b6127b75760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156127e2576000805460ff1961ff0019909116610100171660011790555b6117fd6301ffc9a760e01b612987565b600054610100900460ff168061280b575061280b6126a4565b80612819575060005460ff16155b6128545760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561287f576000805460ff1961ff0019909116610100171660011790555b61288882612a0b565b612898636cdb3d1360e11b612987565b6118b86303a24d0760e21b612987565b60006128b4838361296b565b6128ea57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c23565b506000610c23565b600061134c836001600160a01b038416612a1e565b815460009082106129495760405162461bcd60e51b8152600401808060200182810382526022815260200180612c576022913960400191505060405180910390fd5b82600001828154811061295857fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6001600160e01b031980821614156129e6576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b80516110e8906099906020840190612ae4565b60008181526001830160205260408120548015612ada5783546000198083019190810190600090879083908110612a5157fe5b9060005260206000200154905080876000018481548110612a6e57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612a9e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610c23565b6000915050610c23565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612b2557805160ff1916838001178555612b52565b82800160010185558215612b52579182015b82811115612b52578251825591602001919060010190612b37565b50612b5e929150612b62565b5090565b5b80821115612b5e5760008155600101612b63565b60e01c90565b600060443d1015612b8d57611987565b600481823e6308c379a0612ba18251612b77565b14612bab57611987565b6040513d600319016004823e80513d67ffffffffffffffff8160248401118184111715612bdb5750505050611987565b82840192508251915080821115612bf55750505050611987565b503d83016020828401011115612c0d57505050611987565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e746572456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e73416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373455243313135353a206275726e20616d6f756e7420657863656564732062616c616e6365455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564455243313135353a206275726e2066726f6d20746865207a65726f2061646472657373455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d61746368455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212208082e80af5715fe3fac7824ad3b116a08ca0bb914f0d3fd373b87d6d3d635c7664736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba26469706673582212206bf00ba30bb34af44bf92128b57b7330a2e0d7dda2d608de431952c934fe131f64736f6c634300060c0033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002385760003560e01c80636d6112861162000135578063b9581c5011620000bd578063cc5b715b1162000087578063cc5b715b1462000490578063d547741f146200049a578063dec2deb614620004b1578063e7ece22814620004bb578063edcc12b514620004d25762000238565b8063b9581c501462000441578063c0e312dc146200044b578063ca15c8731462000462578063cb703bff14620004795762000238565b806391d1485411620000ff57806391d1485414620003f2578063a217fddf1462000409578063ade686761462000413578063b626a44f146200042a5762000238565b80636d61128614620003b05780636d6c68e614620003ba578063884cee5a14620003c45780639010d07c14620003db5762000238565b806336568abe11620001c557806350f44280116200018f57806350f4428014620003485780635492d3b514620003615780635573b8b614620003785780636685bde514620003825780636ce681d214620003995762000238565b806336568abe14620002f757806339927cf9146200030e5780633b690b6b14620003345780633fa194ce146200033e5762000238565b8063248a9ca31162000207578063248a9ca314620002a657806328c5e18214620002cc5780632dc151de14620002d65780632f2ff15d14620002e05762000238565b8063029996b8146200023d578063066ee47f14620002495780630b885ac314620002605780630f1a8f741462000277575b600080fd5b62000247620004e9565b005b620002476200025a36600462002b0a565b62000541565b620002476200027136600462002c48565b6200081c565b6200028e620002883660046200298e565b620008bc565b6040516200029d919062002ee3565b60405180910390f35b620002bd620002b73660046200298e565b620008d7565b6040516200029d919062003036565b620002bd620008ec565b6200028e62000937565b62000247620002f1366004620029a7565b62000946565b6200024762000308366004620029a7565b62000996565b620003256200031f36600462002a6d565b620009df565b6040516200029d91906200302b565b620002bd62000a3e565b620002bd62000a44565b6200035262000a57565b6040516200029d919062003099565b620002476200037236600462002bc9565b62000a7a565b6200028e62000cc9565b6200028e6200039336600462002836565b62000cd8565b62000247620003aa36600462002c48565b62000cf3565b6200028e62000e59565b6200028e62000e68565b62000325620003d5366004620029ce565b62000e77565b6200028e620003ec36600462002a2d565b62001008565b6200032562000403366004620029a7565b62001029565b620002bd62001043565b620002476200042436600462002855565b62001048565b620002476200043b3660046200292f565b620012cd565b62000247620013a2565b620002476200045c36600462002a6d565b620013eb565b620002bd620004733660046200298e565b620014b3565b620002476200048a36600462002ab0565b620014cc565b620002bd620015ce565b62000247620004ab366004620029a7565b620015f2565b6200032562001632565b62000247620004cc366004620028e5565b62001642565b62000247620004e336600462002836565b62001835565b62000504600080516020620070918339815191523362001029565b6200052c5760405162461bcd60e51b815260040162000523906200338c565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b6001600160a01b0383166200056a5760405162461bcd60e51b815260040162000523906200350e565b600086866040516020016200058192919062002eb5565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b848301529151919350620005c392910162002ec5565b60405160208183030381529060405280519060200120811415620005fb5760405162461bcd60e51b8152600401620005239062003271565b6000818152606a60205260409020546001600160a01b0316620006325760405162461bcd60e51b81526004016200052390620030e6565b6001600160a01b038086166000908152606b602052604090205416620006588162001883565b620006775760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c590620006a7903390309060040162002ef7565b60206040518083038186803b158015620006c057600080fd5b505afa158015620006d5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006fb91906200296c565b6200071a5760405162461bcd60e51b81526004016200052390620033cd565b604051631ac8311560e21b81526001600160a01b03821690636b20c454906200074c9033908890889060040162002f11565b600060405180830381600087803b1580156200076757600080fd5b505af11580156200077c573d6000803e3d6000fd5b505050506060620007908787878762001889565b6065546000858152606a6020526040908190205490516365e3781f60e01b81529293506001600160a01b03918216926365e3781f92620007dd928e928e929091169087906004016200303f565b600060405180830381600087803b158015620007f857600080fd5b505af11580156200080d573d6000803e3d6000fd5b50505050505050505050505050565b600054610100900460ff16806200083857506200083862001907565b8062000847575060005460ff16155b620008665760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562000892576000805460ff1961ff0019909116610100171660011790555b620008a1868686868662000cf3565b8015620008b4576000805461ff00191690555b505050505050565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200091e919062002ec5565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b6000828152603360205260409020600201546200096790620004036200191a565b620009865760405162461bcd60e51b815260040162000523906200315f565b6200099282826200191e565b5050565b620009a06200191a565b6001600160a01b0316816001600160a01b031614620009d35760405162461bcd60e51b8152600401620005239062003699565b6200099282826200198c565b6000806001600160a01b0316606a6000858560405160200162000a0492919062002eb5565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b60685481565b6000805160206200709183398151915281565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6001600160a01b03831662000aa35760405162461bcd60e51b815260040162000523906200350e565b6000868660405160200162000aba92919062002eb5565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000afc92910162002ec5565b6040516020818303038152906040528051906020012081141562000b345760405162461bcd60e51b8152600401620005239062003271565b6000818152606a60205260409020546001600160a01b031662000b6b5760405162461bcd60e51b81526004016200052390620030e6565b6001600160a01b038086166000908152606b60205260409020541662000b918162001883565b62000bb05760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c59062000be0903390309060040162002ef7565b60206040518083038186803b15801562000bf957600080fd5b505afa15801562000c0e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c3491906200296c565b62000c535760405162461bcd60e51b81526004016200052390620033cd565b604051637a94c56560e11b81526001600160a01b0382169063f5298aca9062000c859033908890889060040162002f55565b600060405180830381600087803b15801562000ca057600080fd5b505af115801562000cb5573d6000803e3d6000fd5b5050505060606200079087878787620019fa565b6065546001600160a01b031681565b606b602052600090815260409020546001600160a01b031681565b600054610100900460ff168062000d0f575062000d0f62001907565b8062000d1e575060005460ff16155b62000d3d5760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562000d69576000805460ff1961ff0019909116610100171660011790555b62000d7362001a5e565b62000d8060003362000986565b62000d9b600080516020620070918339815191523362000986565b62000dc77ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362000986565b8560405160200162000dda919062002ec5565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b031992831617909255606680548784169083161790556067805486841690831617905560698054928516929091169190911790558015620008b4576000805461ff0019169055505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b6065546000906001600160a01b0316331462000ea75760405162461bcd60e51b81526004016200052390620031ae565b606854851415801562000f3957506040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000ee7919062002ec5565b60405160208183030381529060405280519060200120851462000f27576000858152606a60205260409020546001600160a01b0385811691161462000f39565b6069546001600160a01b038581169116145b62000f585760405162461bcd60e51b815260040162000523906200357c565b600062000f66848462001afe565b9050600981600c81111562000f7757fe5b148062000f905750600a81600c81111562000f8e57fe5b145b1562000fa85762000fa2848462001b49565b62000ffc565b600b81600c81111562000fb757fe5b148062000fd05750600c81600c81111562000fce57fe5b145b1562000fe25762000fa2848462001dec565b60405162461bcd60e51b81526004016200052390620036e8565b50600195945050505050565b60008281526033602052604081206200102290836200206a565b9392505050565b600082815260336020526040812062001022908362002078565b600081565b6001600160a01b038316620010715760405162461bcd60e51b815260040162000523906200350e565b6001600160a01b038085166000908152606b6020526040908190205460675491516311be333d60e11b815290831692919091169063237c667a90620010bb90879060040162002ee3565b600060405180830381600087803b158015620010d657600080fd5b505af1158015620010eb573d6000803e3d6000fd5b5050505062001103816001600160a01b031662001883565b620011225760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c59062001152903390309060040162002ef7565b60206040518083038186803b1580156200116b57600080fd5b505afa15801562001180573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011a691906200296c565b620011c55760405162461bcd60e51b81526004016200052390620033cd565b604051631ac8311560e21b81526001600160a01b03821690636b20c45490620011f79033908790879060040162002f11565b600060405180830381600087803b1580156200121257600080fd5b505af115801562001227573d6000803e3d6000fd5b5050505060606200123b8686868662001889565b606554604080518082018252600781526613585a5b9b995d60ca1b602082015260695491516365e3781f60e01b81529394506001600160a01b03928316936365e3781f93620012919316908690600401620030ae565b600060405180830381600087803b158015620012ac57600080fd5b505af1158015620012c1573d6000803e3d6000fd5b50505050505050505050565b620012f97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001029565b620013185760405162461bcd60e51b8152600401620005239062003454565b6200132c816001600160a01b031662001883565b6200134b5760405162461bcd60e51b8152600401620005239062003545565b6001600160a01b038281166000818152606b602052604080822080546001600160a01b0319169486169485179055517f096b3e2c36bc263e90f7577e70dc47b6536fc8d85d467d54f61f91c2ca091c519190a35050565b620013bd600080516020620070918339815191523362001029565b620013dc5760405162461bcd60e51b815260040162000523906200338c565b6069805460ff60a01b19169055565b6066546001600160a01b03163314806200140d57506200140d60003362001029565b6200142c5760405162461bcd60e51b8152600401620005239062003633565b600082826040516020016200144392919062002eb5565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b0316620014935760405162461bcd60e51b81526004016200052390620032c1565b6000908152606a6020526040902080546001600160a01b03191690555050565b600081815260336020526040812062000a38906200208f565b6066546001600160a01b0316331480620014ee5750620014ee60003362001029565b6200150d5760405162461bcd60e51b8152600401620005239062003633565b600083836040516020016200152492919062002eb5565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031615620015755760405162461bcd60e51b81526004016200052390620035fc565b6001600160a01b0382166200159e5760405162461bcd60e51b81526004016200052390620030e6565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b6000828152603360205260409020600201546200161390620004036200191a565b620009d35760405162461bcd60e51b8152600401620005239062003404565b606954600160a01b900460ff1681565b6001600160a01b0383166200166b5760405162461bcd60e51b815260040162000523906200350e565b6001600160a01b038085166000908152606b6020526040908190205460675491516311be333d60e11b815290831692919091169063237c667a90620016b590879060040162002ee3565b600060405180830381600087803b158015620016d057600080fd5b505af1158015620016e5573d6000803e3d6000fd5b50505050620016fd816001600160a01b031662001883565b6200171c5760405162461bcd60e51b8152600401620005239062003662565b60405163e985e9c560e01b81526001600160a01b0382169063e985e9c5906200174c903390309060040162002ef7565b60206040518083038186803b1580156200176557600080fd5b505afa1580156200177a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017a091906200296c565b620017bf5760405162461bcd60e51b81526004016200052390620033cd565b604051637a94c56560e11b81526001600160a01b0382169063f5298aca90620017f19033908790879060040162002f55565b600060405180830381600087803b1580156200180c57600080fd5b505af115801562001821573d6000803e3d6000fd5b5050505060606200123b86868686620019fa565b6200184260003362001029565b620018615760405162461bcd60e51b815260040162000523906200323a565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b3b151590565b6060620018956200245e565b6040805160c081019091528060a0810180600b8152508152602001876001600160a01b03168152602001866001600160a01b0316815260200185815260200184815250905080604051602001620018ed919062003718565b604051602081830303815290604052915050949350505050565b6000620019143062001883565b15905090565b3390565b60008281526033602052604090206200193890826200209c565b156200099257620019486200191a565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020620019a69082620020b3565b156200099257620019b66200191a565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b606062001a0662002494565b6040805160c081019091528060a081018060098152508152602001876001600160a01b03168152602001866001600160a01b0316815260200185815260200184815250905080604051602001620018ed91906200378c565b600054610100900460ff168062001a7a575062001a7a62001907565b8062001a89575060005460ff16155b62001aa85760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562001ad4576000805460ff1961ff0019909116610100171660011790555b62001ade620020ca565b62001ae8620020ca565b801562001afb576000805461ff00191690555b50565b60008062001b0f838501856200298e565b90506020810662001b3b5762001b3262001b2c8483818862003804565b62001afe565b91505062000a38565b62001b328385018562002a4f565b600062001b57838362001afe565b90506000808080600985600c81111562001b6d57fe5b141562001baf5762001b7e62002494565b62001b8a888862002154565b9050806040015194508060200151935080606001519250806080015191505062001cd4565b62001bb9620024cb565b62001bc58888620021a6565b805160408082015160208084015160608501516080909501516001600160a01b038083166000908152606b9094529490922054929a509850929650919450919250168062001cd157606954600160a01b900460ff1662001c395760405162461bcd60e51b81526004016200052390620034d7565b60208201515160405162001c4d90620024f4565b62001c59919062003099565b604051809103906000f08015801562001c76573d6000803e3d6000fd5b506001600160a01b038681166000818152606b602052604080822080546001600160a01b031916948616948517905551939450919290917ff591ef422bd6af456a3cad967032f043099a7d9838494d88ba15d16a89f50b7491a35b50505b6001600160a01b038084166000908152606b60205260409020541662001cfa8162001883565b62001d195760405162461bcd60e51b8152600401620005239062003545565b60405163731133e960e01b81526001600160a01b0382169063731133e99062001d4b9088908790879060040162002fc9565b600060405180830381600087803b15801562001d6657600080fd5b505af115801562001d7b573d6000803e3d6000fd5b50505050806001600160a01b0316846001600160a01b03167f84899afd4ab55115c2eab5a59471e73bc42359e7c3d4e5a3c1aa4837bd20ed5562001dbf86620021f8565b62001dca86620021f8565b60405162001dda92919062002ff9565b60405180910390a35050505050505050565b600062001dfa838362001afe565b9050600080606080600b85600c81111562001e1157fe5b141562001e535762001e226200245e565b62001e2e88886200223a565b9050806040015194508060200151935080606001519250806080015191505062001f78565b62001e5d62002502565b62001e6988886200228c565b805160408082015160208084015160608501516080909501516001600160a01b038083166000908152606b9094529490922054929a509850929650919450919250168062001f7557606954600160a01b900460ff1662001edd5760405162461bcd60e51b81526004016200052390620034d7565b60208201515160405162001ef190620024f4565b62001efd919062003099565b604051809103906000f08015801562001f1a573d6000803e3d6000fd5b506001600160a01b038681166000818152606b602052604080822080546001600160a01b031916948616948517905551939450919290917ff591ef422bd6af456a3cad967032f043099a7d9838494d88ba15d16a89f50b7491a35b50505b6001600160a01b038084166000908152606b60205260409020541662001f9e8162001883565b62001fbd5760405162461bcd60e51b8152600401620005239062003545565b604051630fbfeffd60e11b81526001600160a01b03821690631f7fdffa9062001fef9088908790879060040162002f76565b600060405180830381600087803b1580156200200a57600080fd5b505af11580156200201f573d6000803e3d6000fd5b50505050806001600160a01b0316846001600160a01b03167f84899afd4ab55115c2eab5a59471e73bc42359e7c3d4e5a3c1aa4837bd20ed55858560405162001dda92919062002ff9565b6000620010228383620022de565b600062001022836001600160a01b03841662002327565b600062000a38826200233f565b600062001022836001600160a01b03841662002343565b600062001022836001600160a01b03841662002392565b600054610100900460ff1680620020e65750620020e662001907565b80620020f5575060005460ff16155b620021145760405162461bcd60e51b8152600401620005239062003489565b600054610100900460ff1615801562001ae8576000805460ff1961ff001990911661010017166001179055801562001afb576000805461ff001916905550565b6200215e62002494565b60096200216c848462001afe565b600c8111156200217857fe5b14620021985760405162461bcd60e51b81526004016200052390620032f8565b620010228284018462002e1a565b620021b0620024cb565b600a620021be848462001afe565b600c811115620021ca57fe5b14620021ea5760405162461bcd60e51b815260040162000523906200333c565b620010228284018462002cdb565b6040805160018082528183019092526060916020808301908036833701905050905081816000815181106200222957fe5b602002602001018181525050919050565b620022446200245e565b600b62002252848462001afe565b600c8111156200225e57fe5b146200227e5760405162461bcd60e51b81526004016200052390620035b3565b620010228284018462002ddc565b6200229662002502565b600c620022a4848462001afe565b600c811115620022b057fe5b14620022d05760405162461bcd60e51b81526004016200052390620031e5565b620010228284018462002d61565b81546000908210620023045760405162461bcd60e51b815260040162000523906200311d565b8260000182815481106200231457fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b600062002351838362002327565b620023895750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000a38565b50600062000a38565b60008181526001830160205260408120548015620024535783546000198083019190810190600090879083908110620023c757fe5b9060005260206000200154905080876000018481548110620023e557fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806200241657fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505062000a38565b600091505062000a38565b6040518060a001604052806200247362002517565b81526000602082018190526040820152606080820181905260809091015290565b6040518060a00160405280620024a962002517565b8152600060208201819052604082018190526060820181905260809091015290565b6040518060400160405280620024e062002494565b8152602001620024ef6200252b565b905290565b613819806200387883390190565b6040518060400160405280620024e06200245e565b6040805160208101909152806000620024ef565b6040518060200160405280606081525090565b600082601f8301126200254f578081fd5b81356001600160401b0381111562002565578182fd5b602080820262002577828201620037dd565b838152935081840185830182870184018810156200259457600080fd5b600092505b84831015620025b957803582526001929092019190830190830162002599565b505050505092915050565b60008083601f840112620025d6578182fd5b5081356001600160401b03811115620025ed578182fd5b6020830191508360208285010111156200260657600080fd5b9250929050565b8035600d811062000a3857600080fd5b600082601f8301126200262e578081fd5b81356001600160401b0381111562002644578182fd5b62002659601f8201601f1916602001620037dd565b91508082528360208285010111156200267157600080fd5b8060208401602084013760009082016020015292915050565b6000602082840312156200269c578081fd5b620026a86020620037dd565b9050620026b683836200260d565b815292915050565b600060208284031215620026d0578081fd5b620026dc6020620037dd565b905081356001600160401b03811115620026f557600080fd5b62002703848285016200261d565b82525092915050565b600060a082840312156200271e578081fd5b6200272a60a0620037dd565b90506200273883836200268a565b815260208201356200274a8162003861565b602082015260408201356200275f8162003861565b604082015260608201356001600160401b03808211156200277f57600080fd5b6200278d858386016200253e565b60608401526080840135915080821115620027a757600080fd5b50620027b6848285016200253e565b60808301525092915050565b600060a08284031215620027d4578081fd5b620027e060a0620037dd565b9050620027ee83836200268a565b81526020820135620028008162003861565b60208201526040820135620028158162003861565b80604083015250606082013560608201526080820135608082015292915050565b60006020828403121562002848578081fd5b8135620010228162003861565b600080600080608085870312156200286b578283fd5b8435620028788162003861565b935060208501356200288a8162003861565b925060408501356001600160401b0380821115620028a6578384fd5b620028b4888389016200253e565b93506060870135915080821115620028ca578283fd5b50620028d9878288016200253e565b91505092959194509250565b60008060008060808587031215620028fb578384fd5b8435620029088162003861565b935060208501356200291a8162003861565b93969395505050506040820135916060013590565b6000806040838503121562002942578182fd5b82356200294f8162003861565b91506020830135620029618162003861565b809150509250929050565b6000602082840312156200297e578081fd5b8151801515811462001022578182fd5b600060208284031215620029a0578081fd5b5035919050565b60008060408385031215620029ba578182fd5b823591506020830135620029618162003861565b60008060008060608587031215620029e4578182fd5b843593506020850135620029f88162003861565b925060408501356001600160401b0381111562002a13578283fd5b62002a2187828801620025c4565b95989497509550505050565b6000806040838503121562002a40578182fd5b50508035926020909101359150565b60006020828403121562002a61578081fd5b6200102283836200260d565b6000806020838503121562002a80578182fd5b82356001600160401b0381111562002a96578283fd5b62002aa485828601620025c4565b90969095509350505050565b60008060006040848603121562002ac5578081fd5b83356001600160401b0381111562002adb578182fd5b62002ae986828701620025c4565b909450925050602084013562002aff8162003861565b809150509250925092565b60008060008060008060a0878903121562002b23578384fd5b86356001600160401b038082111562002b3a578586fd5b62002b488a838b01620025c4565b90985096506020890135915062002b5f8262003861565b90945060408801359062002b738262003861565b9093506060880135908082111562002b89578384fd5b62002b978a838b016200253e565b9350608089013591508082111562002bad578283fd5b5062002bbc89828a016200253e565b9150509295509295509295565b60008060008060008060a0878903121562002be2578384fd5b86356001600160401b0381111562002bf8578485fd5b62002c0689828a01620025c4565b909750955050602087013562002c1c8162003861565b9350604087013562002c2e8162003861565b959894975092956060810135946080909101359350915050565b600080600080600060a0868803121562002c60578283fd5b85356001600160401b0381111562002c76578384fd5b62002c84888289016200261d565b955050602086013562002c978162003861565b9350604086013562002ca98162003861565b9250606086013562002cbb8162003861565b9150608086013562002ccd8162003861565b809150509295509295909350565b60006020828403121562002ced578081fd5b81356001600160401b038082111562002d04578283fd5b9083019060c0828603121562002d18578283fd5b62002d246040620037dd565b62002d308684620027c2565b815260a08301358281111562002d44578485fd5b62002d5287828601620026be565b60208301525095945050505050565b60006020828403121562002d73578081fd5b81356001600160401b038082111562002d8a578283fd5b908301906040828603121562002d9e578283fd5b62002daa6040620037dd565b82358281111562002db9578485fd5b62002dc7878286016200270c565b82525060208301358281111562002d44578485fd5b60006020828403121562002dee578081fd5b81356001600160401b0381111562002e04578182fd5b62002e12848285016200270c565b949350505050565b600060a0828403121562002e2c578081fd5b620010228383620027c2565b6000815180845260208085019450808401835b8381101562002e695781518752958201959082019060010162002e4b565b509495945050505050565b6000815180845262002e8e8160208601602086016200382e565b601f01601f19169290920160200192915050565b8051600d811062002eaf57fe5b90915250565b6000828483379101908152919050565b6000825162002ed98184602087016200382e565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b038416815260606020820181905260009062002f379083018562002e38565b828103604084015262002f4b818562002e38565b9695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b038416815260806020820181905260009062002f9c9083018562002e38565b828103604084015262002fb0818562002e38565b8381036060909401939093525081526020019392505050565b6001600160a01b039390931683526020830191909152604082015260806060820181905260009082015260a00190565b6000604082526200300e604083018562002e38565b828103602084015262003022818562002e38565b95945050505050565b901515815260200190565b90815260200190565b60006060825284606083015284866080840137608085830181018290526001600160a01b0385166020840152601f8601601f1916830183810382016040850152906200308e9082018562002e74565b979650505050505050565b60006020825262001022602083018462002e74565b600060608252620030c3606083018662002e74565b6001600160a01b0385166020840152828103604084015262002f4b818562002e74565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b60208082526035908201527f4d6573736167652074797065206973206e6f742045524331313535426174636860408201527420b7322a37b5b2b724b73337903a3930b739b332b960591b606082015260800190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526024908201527f4d6573736167652074797065206973206e6f742045524331313535207472616e60408201526339b332b960e11b606082015260800190565b60208082526030908201527f4d6573736167652074797065206973206e6f742045524331313535416e64546f60408201526f35b2b724b73337903a3930b739b332b960811b606082015260800190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60208082526019908201527f4e6f7420616c6c6f776564204552433131353520546f6b656e00000000000000604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601c908201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604082015260600190565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b60208082526029908201527f4d6573736167652074797065206973206e6f7420455243313135354261746368604082015268103a3930b739b332b960b91b606082015260800190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b60208082526018908201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60208082526016908201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604082015260600190565b6000602082526200372e60208301845162002ea2565b60208301516001600160a01b039081166040848101919091528401511660608084019190915283015160a060808401526200376d60c084018262002e38565b90506080840151601f198483030160a085015262003022828262002e38565b600060a082019050620037a182845162002ea2565b602083015160018060a01b0380821660208501528060408601511660408501525050606083015160608301526080830151608083015292915050565b6040518181016001600160401b0381118282101715620037fc57600080fd5b604052919050565b6000808585111562003814578182fd5b8386111562003821578182fd5b5050820193919092039150565b60005b838110156200384b57818101518382015260200162003831565b838111156200385b576000848401525b50505050565b6001600160a01b038116811462001afb57600080fdfe60806040523480156200001157600080fd5b506040516200381938038062003819833981810160405260208110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052505050620001026200017360201b620017601760201c565b62000118816200023160201b620018121760201c565b6200012d620002fb60201b620018cd1760201c565b62000148600080516020620037f983398151915280620003a3565b6200016c600080516020620037f983398151915262000166620003f5565b620003f9565b5062000872565b600054610100900460ff16806200018f57506200018f62000405565b806200019e575060005460ff16155b620001db5760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff1615801562000207576000805460ff1961ff0019909116610100171660011790555b6200021162000423565b6200021b62000423565b80156200022e576000805461ff00191690555b50565b600054610100900460ff16806200024d57506200024d62000405565b806200025c575060005460ff16155b620002995760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff16158015620002c5576000805460ff1961ff0019909116610100171660011790555b620002cf62000423565b620002d9620004cb565b620002e48262000571565b8015620002f7576000805461ff00191690555b5050565b600054610100900460ff16806200031757506200031762000405565b8062000326575060005460ff16155b620003635760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200038f576000805460ff1961ff0019909116610100171660011790555b6200039962000423565b62000211620004cb565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620002f7828262000634565b60006200041d30620006af60201b6200196a1760201c565b15905090565b600054610100900460ff16806200043f57506200043f62000405565b806200044e575060005460ff16155b6200048b5760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200021b576000805460ff1961ff00199091166101001716600117905580156200022e576000805461ff001916905550565b600054610100900460ff1680620004e75750620004e762000405565b80620004f6575060005460ff16155b620005335760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff161580156200055f576000805460ff1961ff0019909116610100171660011790555b6200021b6301ffc9a760e01b620006b5565b600054610100900460ff16806200058d57506200058d62000405565b806200059c575060005460ff16155b620005d95760405162461bcd60e51b815260040180806020018281038252602e815260200180620037cb602e913960400191505060405180910390fd5b600054610100900460ff1615801562000605576000805460ff1961ff0019909116610100171660011790555b62000610826200073a565b62000622636cdb3d1360e11b620006b5565b620002e46303a24d0760e21b620006b5565b60008281526033602090815260409091206200065b918390620019706200074f821b17901c565b15620002f7576200066b620003f5565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b6001600160e01b0319808216141562000715576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b8051620002f7906099906020840190620007d6565b600062000766836001600160a01b0384166200076f565b90505b92915050565b60006200077d8383620007be565b620007b55750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000769565b50600062000769565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200081957805160ff191683800117855562000849565b8280016001018555821562000849579182015b82811115620008495782518255916020019190600101906200082c565b50620008579291506200085b565b5090565b5b808211156200085757600081556001016200085c565b612f4980620008826000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c87314610a3d578063d539139314610a5a578063d547741f14610a62578063e985e9c514610a8e578063f242432a14610abc578063f5298aca14610b8557610136565b8063731133e9146108dc5780639010d07c1461099c57806391d14854146109db578063a217fddf14610a07578063a22cb46514610a0f57610136565b80632eb2c2d6116100ff5780632eb2c2d61461041d5780632f2ff15d146105de57806336568abe1461060a5780634e1273f4146106365780636b20c454146107a957610136565b8062fdd58e1461013b57806301ffc9a7146101795780630e89341c146101b45780631f7fdffa14610246578063248a9ca314610400575b600080fd5b6101676004803603604081101561015157600080fd5b506001600160a01b038135169060200135610bb7565b60408051918252519081900360200190f35b6101a06004803603602081101561018f57600080fd5b50356001600160e01b031916610c29565b604080519115158252519081900360200190f35b6101d1600480360360208110156101ca57600080fd5b5035610c48565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103fe6004803603608081101561025c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561028657600080fd5b82018360208201111561029857600080fd5b803590602001918460208302840111600160201b831117156102b957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561030857600080fd5b82018360208201111561031a57600080fd5b803590602001918460208302840111600160201b8311171561033b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561038a57600080fd5b82018360208201111561039c57600080fd5b803590602001918460018302840111600160201b831117156103bd57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ce0945050505050565b005b6101676004803603602081101561041657600080fd5b5035610d6d565b6103fe600480360360a081101561043357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561046657600080fd5b82018360208201111561047857600080fd5b803590602001918460208302840111600160201b8311171561049957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156104e857600080fd5b8201836020820111156104fa57600080fd5b803590602001918460208302840111600160201b8311171561051b57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561056a57600080fd5b82018360208201111561057c57600080fd5b803590602001918460018302840111600160201b8311171561059d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610d82945050505050565b6103fe600480360360408110156105f457600080fd5b50803590602001356001600160a01b0316611085565b6103fe6004803603604081101561062057600080fd5b50803590602001356001600160a01b03166110ec565b6107596004803603604081101561064c57600080fd5b810190602081018135600160201b81111561066657600080fd5b82018360208201111561067857600080fd5b803590602001918460208302840111600160201b8311171561069957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156106e857600080fd5b8201836020820111156106fa57600080fd5b803590602001918460208302840111600160201b8311171561071b57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061114d945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561079557818101518382015260200161077d565b505050509050019250505060405180910390f35b6103fe600480360360608110156107bf57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156107e957600080fd5b8201836020820111156107fb57600080fd5b803590602001918460208302840111600160201b8311171561081c57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561086b57600080fd5b82018360208201111561087d57600080fd5b803590602001918460208302840111600160201b8311171561089e57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611239945050505050565b6103fe600480360360808110156108f257600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561092857600080fd5b82018360208201111561093a57600080fd5b803590602001918460018302840111600160201b8311171561095b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506112b2945050505050565b6109bf600480360360408110156109b257600080fd5b5080359060200135611334565b604080516001600160a01b039092168252519081900360200190f35b6101a0600480360360408110156109f157600080fd5b50803590602001356001600160a01b0316611353565b61016761136b565b6103fe60048036036040811015610a2557600080fd5b506001600160a01b0381351690602001351515611370565b61016760048036036020811015610a5357600080fd5b503561145f565b610167611476565b6103fe60048036036040811015610a7857600080fd5b50803590602001356001600160a01b031661149a565b6101a060048036036040811015610aa457600080fd5b506001600160a01b03813581169160200135166114f3565b6103fe600480360360a0811015610ad257600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b811115610b1157600080fd5b820183602082011115610b2357600080fd5b803590602001918460018302840111600160201b83111715610b4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611521945050505050565b6103fe60048036036060811015610b9b57600080fd5b506001600160a01b0381351690602081013590604001356116ec565b60006001600160a01b038316610bfe5760405162461bcd60e51b815260040180806020018281038252602b815260200180612cd0602b913960400191505060405180910390fd5b5060008181526097602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526065602052604090205460ff1690565b60998054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610cd45780601f10610ca957610100808354040283529160200191610cd4565b820191906000526020600020905b815481529060010190602001808311610cb757829003601f168201915b50505050509050919050565b610d117f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611353565b610d5b576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461198a565b50505050565b60009081526033602052604090206002015490565b8151835114610dc25760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6001600160a01b038416610e075760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b610e0f611985565b6001600160a01b0316856001600160a01b03161480610e3a5750610e3a85610e35611985565b6114f3565b610e755760405162461bcd60e51b8152600401808060200182810382526032815260200180612d9d6032913960400191505060405180910390fd5b6000610e7f611985565b9050610e8f81878787878761107d565b60005b8451811015610f95576000858281518110610ea957fe5b602002602001015190506000858381518110610ec157fe5b60200260200101519050610f2e816040518060600160405280602a8152602001612e20602a91396097600086815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b60008381526097602090815260408083206001600160a01b038e811685529252808320939093558a1681522054610f659082611c76565b60009283526097602090815260408085206001600160a01b038c1686529091529092209190915550600101610e92565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561101b578181015183820152602001611003565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561105a578181015183820152602001611042565b5050505090500194505050505060405180910390a461107d818787878787611cd0565b505050505050565b6000828152603360205260409020600201546110a390610d0c611985565b6110de5760405162461bcd60e51b815260040180806020018281038252602f815260200180612ca1602f913960400191505060405180910390fd5b6110e88282611f4f565b5050565b6110f4611985565b6001600160a01b0316816001600160a01b0316146111435760405162461bcd60e51b815260040180806020018281038252602f815260200180612ee5602f913960400191505060405180910390fd5b6110e88282611fb8565b6060815183511461118f5760405162461bcd60e51b8152600401808060200182810382526029815260200180612e736029913960400191505060405180910390fd5b6060835167ffffffffffffffff811180156111a957600080fd5b506040519080825280602002602001820160405280156111d3578160200160208202803683370190505b50905060005b8451811015611231576112128582815181106111f157fe5b602002602001015185838151811061120557fe5b6020026020010151610bb7565b82828151811061121e57fe5b60209081029190910101526001016111d9565b509392505050565b611241611985565b6001600160a01b0316836001600160a01b03161480611267575061126783610e35611985565b6112a25760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612021565b505050565b6112de7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610d0c611985565b611328576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610d678484848461228f565b600082815260336020526040812061134c9083612390565b9392505050565b600082815260336020526040812061134c908361239c565b600081565b816001600160a01b0316611382611985565b6001600160a01b031614156113c85760405162461bcd60e51b8152600401808060200182810382526029815260200180612e4a6029913960400191505060405180910390fd5b80609860006113d5611985565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611419611985565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b6000818152603360205260408120610c23906123b1565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6000828152603360205260409020600201546114b890610d0c611985565b6111435760405162461bcd60e51b8152600401808060200182810382526030815260200180612d486030913960400191505060405180910390fd5b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166115665760405162461bcd60e51b8152600401808060200182810382526025815260200180612d786025913960400191505060405180910390fd5b61156e611985565b6001600160a01b0316856001600160a01b03161480611594575061159485610e35611985565b6115cf5760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b60006115d9611985565b90506115f98187876115ea886123bc565b6115f3886123bc565b8761107d565b611640836040518060600160405280602a8152602001612e20602a913960008781526097602090815260408083206001600160a01b038d1684529091529020549190611bdf565b60008581526097602090815260408083206001600160a01b038b811685529252808320939093558716815220546116779084611c76565b60008581526097602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461107d818787878787612400565b6116f4611985565b6001600160a01b0316836001600160a01b0316148061171a575061171a83610e35611985565b6117555760405162461bcd60e51b8152600401808060200182810382526029815260200180612d1f6029913960400191505060405180910390fd5b6112ad838383612571565b600054610100900460ff168061177957506117796126a4565b80611787575060005460ff16155b6117c25760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117ed576000805460ff1961ff0019909116610100171660011790555b6117f56126b5565b6117fd6126b5565b801561180f576000805461ff00191690555b50565b600054610100900460ff168061182b575061182b6126a4565b80611839575060005460ff16155b6118745760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561189f576000805460ff1961ff0019909116610100171660011790555b6118a76126b5565b6118af612755565b6118b8826127f2565b80156110e8576000805461ff00191690555050565b600054610100900460ff16806118e657506118e66126a4565b806118f4575060005460ff16155b61192f5760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561195a576000805460ff1961ff0019909116610100171660011790555b6119626126b5565b6117f5612755565b3b151590565b600061134c836001600160a01b0384166128a8565b335b90565b6001600160a01b0384166119cf5760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b8151835114611a0f5760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b6000611a19611985565b9050611a2a8160008787878761107d565b60005b8451811015611aee57611aa560976000878481518110611a4957fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002054858381518110611a8f57fe5b6020026020010151611c7690919063ffffffff16565b60976000878481518110611ab557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101611a2d565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015611b75578181015183820152602001611b5d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015611bb4578181015183820152602001611b9c565b5050505090500194505050505060405180910390a4611bd881600087878787611cd0565b5050505050565b60008184841115611c6e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c33578181015183820152602001611c1b565b50505050905090810190601f168015611c605780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008282018381101561134c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b611ce2846001600160a01b031661196a565b1561107d57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015611d70578181015183820152602001611d58565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015611daf578181015183820152602001611d97565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015611deb578181015183820152602001611dd3565b50505050905090810190601f168015611e185780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b158015611e3d57600080fd5b505af1925050508015611e6257506040513d6020811015611e5d57600080fd5b505160015b611ef757611e6e612b7d565b80611e795750611ec0565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315611c33578181015183820152602001611c1b565b60405162461bcd60e51b8152600401808060200182810382526034815260200180612c236034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b50505050505050565b6000828152603360205260409020611f679082611970565b156110e857611f74611985565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020611fd090826128f2565b156110e857611fdd611985565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b0383166120665760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b80518251146120a65760405162461bcd60e51b8152600401808060200182810382526028815260200180612e9c6028913960400191505060405180910390fd5b60006120b0611985565b90506120d08185600086866040518060200160405280600081525061107d565b60005b83518110156121ae576121658382815181106120eb57fe5b6020026020010151604051806060016040528060248152602001612cfb602491396097600088868151811061211c57fe5b602002602001015181526020019081526020016000206000896001600160a01b03166001600160a01b0316815260200190815260200160002054611bdf9092919063ffffffff16565b6097600086848151811061217557fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038a1682529092529020556001016120d3565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561223557818101518382015260200161221d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561227457818101518382015260200161225c565b5050505090500194505050505060405180910390a450505050565b6001600160a01b0384166122d45760405162461bcd60e51b8152600401808060200182810382526021815260200180612ec46021913960400191505060405180910390fd5b60006122de611985565b90506122f0816000876115ea886123bc565b60008481526097602090815260408083206001600160a01b038916845290915290205461231d9084611c76565b60008581526097602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a4611bd881600087878787612400565b600061134c8383612907565b600061134c836001600160a01b03841661296b565b6000610c2382612983565b6040805160018082528183019092526060918291906020808301908036833701905050905082816000815181106123ef57fe5b602090810291909101015292915050565b612412846001600160a01b031661196a565b1561107d57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156124a1578181015183820152602001612489565b50505050905090810190601f1680156124ce5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b1580156124f157600080fd5b505af192505050801561251657506040513d602081101561251157600080fd5b505160015b61252257611e6e612b7d565b6001600160e01b0319811663f23a6e6160e01b14611f465760405162461bcd60e51b8152600401808060200182810382526028815260200180612c796028913960400191505060405180910390fd5b6001600160a01b0383166125b65760405162461bcd60e51b8152600401808060200182810382526023815260200180612dfd6023913960400191505060405180910390fd5b60006125c0611985565b90506125f0818560006125d2876123bc565b6125db876123bc565b6040518060200160405280600081525061107d565b61263782604051806060016040528060248152602001612cfb6024913960008681526097602090815260408083206001600160a01b038b1684529091529020549190611bdf565b60008481526097602090815260408083206001600160a01b03808a16808652918452828520959095558151888152928301879052815193949093908616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a450505050565b60006126af3061196a565b15905090565b600054610100900460ff16806126ce57506126ce6126a4565b806126dc575060005460ff16155b6127175760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156117fd576000805460ff1961ff001990911661010017166001179055801561180f576000805461ff001916905550565b600054610100900460ff168061276e575061276e6126a4565b8061277c575060005460ff16155b6127b75760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff161580156127e2576000805460ff1961ff0019909116610100171660011790555b6117fd6301ffc9a760e01b612987565b600054610100900460ff168061280b575061280b6126a4565b80612819575060005460ff16155b6128545760405162461bcd60e51b815260040180806020018281038252602e815260200180612dcf602e913960400191505060405180910390fd5b600054610100900460ff1615801561287f576000805460ff1961ff0019909116610100171660011790555b61288882612a0b565b612898636cdb3d1360e11b612987565b6118b86303a24d0760e21b612987565b60006128b4838361296b565b6128ea57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c23565b506000610c23565b600061134c836001600160a01b038416612a1e565b815460009082106129495760405162461bcd60e51b8152600401808060200182810382526022815260200180612c576022913960400191505060405180910390fd5b82600001828154811061295857fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6001600160e01b031980821614156129e6576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b80516110e8906099906020840190612ae4565b60008181526001830160205260408120548015612ada5783546000198083019190810190600090879083908110612a5157fe5b9060005260206000200154905080876000018481548110612a6e57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612a9e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610c23565b6000915050610c23565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612b2557805160ff1916838001178555612b52565b82800160010185558215612b52579182015b82811115612b52578251825591602001919060010190612b37565b50612b5e929150612b62565b5090565b5b80821115612b5e5760008155600101612b63565b60e01c90565b600060443d1015612b8d57611987565b600481823e6308c379a0612ba18251612b77565b14612bab57611987565b6040513d600319016004823e80513d67ffffffffffffffff8160248401118184111715612bdb5750505050611987565b82840192508251915080821115612bf55750505050611987565b503d83016020828401011115612c0d57505050611987565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e746572456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e73416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373455243313135353a206275726e20616d6f756e7420657863656564732062616c616e6365455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564455243313135353a206275726e2066726f6d20746865207a65726f2061646472657373455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d61746368455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212208082e80af5715fe3fac7824ad3b116a08ca0bb914f0d3fd373b87d6d3d635c7664736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba26469706673582212206bf00ba30bb34af44bf92128b57b7330a2e0d7dda2d608de431952c934fe131f64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC20.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC20.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC20.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC20.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC20.json new file mode 100644 index 000000000..2b8764108 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC20.json @@ -0,0 +1,730 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerERC20", + "sourceName": "contracts/schain/TokenManagers/TokenManagerERC20.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc20OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnSchain", + "type": "address" + } + ], + "name": "ERC20TokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc20OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnSchain", + "type": "address" + } + ], + "name": "ERC20TokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc20OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnSchain", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ERC20TokenReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "erc20OnMainnet", + "type": "address" + }, + { + "internalType": "contract ERC20OnChain", + "name": "erc20OnSchain", + "type": "address" + } + ], + "name": "addERC20TokenByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "clonesErc20", + "outputs": [ + { + "internalType": "contract ERC20OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract CommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exitToMainERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract MessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract TokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalSupplyOnMainnet", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferToSchainERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50615098806100206000396000f3fe60806040523480156200001157600080fd5b50600436106200022c5760003560e01c80635573b8b61162000135578063b9581c5011620000bd578063cc5b715b1162000087578063cc5b715b146200046d578063d547741f1462000477578063dec2deb6146200048e578063edcc12b51462000498578063f429e38314620004af576200022c565b8063b9581c50146200041e578063c0e312dc1462000428578063ca15c873146200043f578063cb703bff1462000456576200022c565b8063884cee5a11620000ff578063884cee5a14620003cf5780639010d07c14620003e657806391d1485414620003fd578063a217fddf1462000414576200022c565b80635573b8b6146200039a5780636ce681d214620003a45780636d61128614620003bb5780636d6c68e614620003c5576200022c565b80632dc151de11620001b95780633b690b6b11620001835780633b690b6b14620003565780633fa194ce14620003605780634d58c889146200036a57806350f442801462000381576200022c565b80632dc151de14620002f85780632f2ff15d146200030257806336568abe146200031957806339927cf91462000330576200022c565b8063248a9ca311620001fb578063248a9ca3146200029a57806328c5e18214620002c05780632baaf64314620002ca5780632d6eea0614620002e1576200022c565b8063029996b814620002315780630472e00a146200023d5780630b885ac314620002545780630f1a8f74146200026b575b600080fd5b6200023b620004c6565b005b6200023b6200024e3660046200242a565b6200051e565b6200023b62000265366004620024a0565b6200093d565b620002826200027c366004620022ab565b62000953565b604051620002919190620026e9565b60405180910390f35b620002b1620002ab366004620022ab565b6200096e565b6040516200029191906200275f565b620002b162000983565b6200023b620002db36600462002207565b620009ce565b62000282620002f2366004620021e8565b62000d97565b6200028262000db2565b6200023b62000313366004620022c4565b62000dc1565b6200023b6200032a366004620022c4565b62000e11565b62000347620003413660046200238b565b62000e5a565b60405162000291919062002754565b620002b162000eb9565b620002b162000ebf565b6200023b6200037b3660046200224c565b62000ed2565b6200038b6200103c565b604051620002919190620027c2565b620002826200105f565b6200023b620003b5366004620024a0565b6200106e565b62000282620011d5565b62000282620011e4565b62000347620003e0366004620022eb565b620011f3565b62000282620003f73660046200234b565b62001369565b620003476200040e366004620022c4565b6200138a565b620002b1620013a4565b6200023b620013a9565b6200023b620004393660046200238b565b620013f2565b620002b162000450366004620022ab565b620014ba565b6200023b62000467366004620023cf565b620014d3565b620002b1620015d5565b6200023b62000488366004620022c4565b620015f9565b6200034762001639565b6200023b620004a9366004620021e8565b62001649565b620002b1620004c0366004620021e8565b62001697565b620004e160008051602062005043833981519152336200138a565b620005095760405162461bcd60e51b8152600401620005009062002a65565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b6001600160a01b038216620005475760405162461bcd60e51b8152600401620005009062002cae565b600085856040516020016200055e929190620026bb565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b848301529151919350620005a0929101620026cb565b60405160208183030381529060405280519060200120811415620005d85760405162461bcd60e51b81526004016200050090620029b0565b6000818152606a60205260409020546001600160a01b03166200060f5760405162461bcd60e51b815260040162000500906200284b565b6001600160a01b038085166000908152606b6020526040902054166200063581620016a9565b620006545760405162461bcd60e51b8152600401620005009062002e42565b6040516370a0823160e01b815283906001600160a01b038316906370a082319062000684903390600401620026e9565b60206040518083038186803b1580156200069d57600080fd5b505afa158015620006b2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006d8919062002674565b1015620006f95760405162461bcd60e51b8152600401620005009062002aa6565b604051636eb1769f60e11b815283906001600160a01b0383169063dd62ed3e906200072b9033903090600401620026fd565b60206040518083038186803b1580156200074457600080fd5b505afa15801562000759573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200077f919062002674565b1015620007a05760405162461bcd60e51b8152600401620005009062002bdc565b6040516323b872dd60e01b81526001600160a01b038216906323b872dd90620007d29033903090889060040162002717565b602060405180830381600087803b158015620007ed57600080fd5b505af115801562000802573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000828919062002289565b620008475760405162461bcd60e51b8152600401620005009062002da5565b604051630852cd8d60e31b81526001600160a01b038216906342966c6890620008759086906004016200275f565b600060405180830381600087803b1580156200089057600080fd5b505af1158015620008a5573d6000803e3d6000fd5b50506065546000858152606a60205260409020546001600160a01b0391821693506365e3781f92508a918a9116620008df8a8a8a620016af565b6040518563ffffffff1660e01b815260040162000900949392919062002768565b600060405180830381600087803b1580156200091b57600080fd5b505af115801562000930573d6000803e3d6000fd5b5050505050505050505050565b6200094c85858585856200106e565b5050505050565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009b59190620026cb565b6040516020818303038152906040528051906020012081565b6001600160a01b038216620009f75760405162461bcd60e51b8152600401620005009062002cae565b6067546040516311be333d60e11b81526001600160a01b039091169063237c667a9062000a29908590600401620026e9565b600060405180830381600087803b15801562000a4457600080fd5b505af115801562000a59573d6000803e3d6000fd5b505050506001600160a01b038381166000908152606b60205260409020541662000a8381620016a9565b62000aa25760405162461bcd60e51b8152600401620005009062002e42565b6040516370a0823160e01b815282906001600160a01b038316906370a082319062000ad2903390600401620026e9565b60206040518083038186803b15801562000aeb57600080fd5b505afa15801562000b00573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b26919062002674565b101562000b475760405162461bcd60e51b8152600401620005009062002aa6565b604051636eb1769f60e11b815282906001600160a01b0383169063dd62ed3e9062000b799033903090600401620026fd565b60206040518083038186803b15801562000b9257600080fd5b505afa15801562000ba7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bcd919062002674565b101562000bee5760405162461bcd60e51b8152600401620005009062002bdc565b6040516323b872dd60e01b81526001600160a01b038216906323b872dd9062000c209033903090879060040162002717565b602060405180830381600087803b15801562000c3b57600080fd5b505af115801562000c50573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c76919062002289565b62000c955760405162461bcd60e51b8152600401620005009062002da5565b604051630852cd8d60e31b81526001600160a01b038216906342966c689062000cc39085906004016200275f565b600060405180830381600087803b15801562000cde57600080fd5b505af115801562000cf3573d6000803e3d6000fd5b505060655460408051808201909152600781526613585a5b9b995d60ca1b60208201526069546001600160a01b0392831694506365e3781f935090911662000d3d888888620016af565b6040518463ffffffff1660e01b815260040162000d5d93929190620027d7565b600060405180830381600087803b15801562000d7857600080fd5b505af115801562000d8d573d6000803e3d6000fd5b5050505050505050565b606b602052600090815260409020546001600160a01b031681565b6066546001600160a01b031681565b60008281526033602052604090206002015462000de2906200040e62001726565b62000e015760405162461bcd60e51b81526004016200050090620028f3565b62000e0d82826200172a565b5050565b62000e1b62001726565b6001600160a01b0316816001600160a01b03161462000e4e5760405162461bcd60e51b8152600401620005009062002e79565b62000e0d828262001798565b6000806001600160a01b0316606a6000858560405160200162000e7f929190620026bb565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b60685481565b6000805160206200504383398151915281565b62000efe7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba8336200138a565b62000f1d5760405162461bcd60e51b8152600401620005009062002b22565b62000f31816001600160a01b0316620016a9565b62000f505760405162461bcd60e51b8152600401620005009062002ce5565b806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000f8a57600080fd5b505afa15801562000f9f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fc5919062002674565b1562000fe55760405162461bcd60e51b8152600401620005009062002ba5565b6001600160a01b038281166000818152606b602052604080822080546001600160a01b0319169486169485179055517fc6e93524baaa4770b94da082aa0caeac9ba78c87f7edc7c3d2820f2e9fdf400a9190a35050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b600054610100900460ff16806200108a57506200108a62001806565b8062001099575060005460ff16155b620010b85760405162461bcd60e51b8152600401620005009062002b57565b600054610100900460ff16158015620010e4576000805460ff1961ff0019909116610100171660011790555b620010ee62001819565b620010fb60003362000e01565b62001116600080516020620050438339815191523362000e01565b620011427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362000e01565b85604051602001620011559190620026cb565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b031992831617909255606680548784169083161790556067805486841690831617905560698054928516929091169190911790558015620011cd576000805461ff00191690555b505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b6065546000906001600160a01b03163314620012235760405162461bcd60e51b8152600401620005009062002942565b6068548514158015620012b557506040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620012639190620026cb565b604051602081830303815290604052805190602001208514620012a3576000858152606a60205260409020546001600160a01b03858116911614620012b5565b6069546001600160a01b038581169116145b620012d45760405162461bcd60e51b8152600401620005009062002d1c565b6000620012e28484620018b9565b9050600481600c811115620012f357fe5b14806200130c5750600381600c8111156200130a57fe5b145b1562001343576200131e848462001904565b6200133d5760405162461bcd60e51b8152600401620005009062002a37565b6200135d565b60405162461bcd60e51b8152600401620005009062002ec8565b50600195945050505050565b600082815260336020526040812062001383908362001caf565b9392505050565b600082815260336020526040812062001383908362001cbd565b600081565b620013c460008051602062005043833981519152336200138a565b620013e35760405162461bcd60e51b8152600401620005009062002a65565b6069805460ff60a01b19169055565b6066546001600160a01b0316331480620014145750620014146000336200138a565b620014335760405162461bcd60e51b8152600401620005009062002e13565b600082826040516020016200144a929190620026bb565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b03166200149a5760405162461bcd60e51b8152600401620005009062002a00565b6000908152606a6020526040902080546001600160a01b03191690555050565b600081815260336020526040812062000eb39062001cd4565b6066546001600160a01b0316331480620014f55750620014f56000336200138a565b620015145760405162461bcd60e51b8152600401620005009062002e13565b600083836040516020016200152b929190620026bb565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b0316156200157c5760405162461bcd60e51b8152600401620005009062002ddc565b6001600160a01b038216620015a55760405162461bcd60e51b815260040162000500906200284b565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b6000828152603360205260409020600201546200161a906200040e62001726565b62000e4e5760405162461bcd60e51b8152600401620005009062002ad2565b606954600160a01b900460ff1681565b620016566000336200138a565b620016755760405162461bcd60e51b8152600401620005009062002979565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b606c6020526000908152604090205481565b3b151590565b6060620016bb62001fbd565b6040805160a0810190915280608081018060028152508152602001866001600160a01b03168152602001856001600160a01b03168152602001848152509050806040516020016200170d919062002ef8565b6040516020818303038152906040529150509392505050565b3390565b600082815260336020526040902062001744908262001ce1565b1562000e0d576200175462001726565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020620017b2908262001cf8565b1562000e0d57620017c262001726565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60006200181330620016a9565b15905090565b600054610100900460ff16806200183557506200183562001806565b8062001844575060005460ff16155b620018635760405162461bcd60e51b8152600401620005009062002b57565b600054610100900460ff161580156200188f576000805460ff1961ff0019909116610100171660011790555b6200189962001d0f565b620018a362001d0f565b8015620018b6576000805461ff00191690555b50565b600080620018ca83850185620022ab565b905060208106620018f657620018ed620018e78483818862002f69565b620018b9565b91505062000eb3565b620018ed838501856200236d565b600080620019138484620018b9565b9050600080808080600386600c8111156200192a57fe5b141562001990576200193b62001fed565b620019478a8a62001d99565b8051604080820151602080840151606090940151948101516001600160a01b038086166000908152606b9093529390912054919a5092985092965090945016915062001ac29050565b6200199a6200200f565b620019a68a8a62001deb565b8051604080820151602080840151606090940151818601516001600160a01b038087166000908152606b9094529490922054929b5093995092975091955016925090508162001ac057606954600160a01b900460ff1662001a1b5760405162461bcd60e51b8152600401620005009062002c77565b80604001516000015181604001516040015160405162001a3b906200203f565b62001a4892919062002819565b604051809103906000f08015801562001a65573d6000803e3d6000fd5b506001600160a01b038681166000818152606b602052604080822080546001600160a01b031916948616948517905551939550919290917fcdae5f6ddbda7847ad809fcd087e35946ef42729ff7ecdbcc81a03eb3a52ab2891a35b505b62001ad6816001600160a01b0316620016a9565b62001af55760405162461bcd60e51b8152600401620005009062002ce5565b6001600160a01b0381166000908152606c6020526040902054821462001b31576001600160a01b0381166000908152606c602052604090208290555b606c6000826001600160a01b03166001600160a01b031681526020019081526020016000205483826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562001b9257600080fd5b505afa15801562001ba7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bcd919062002674565b01111562001bef5760405162461bcd60e51b81526004016200050090620028c4565b6040516340c10f1960e01b81526001600160a01b038216906340c10f199062001c1f90889087906004016200273b565b600060405180830381600087803b15801562001c3a57600080fd5b505af115801562001c4f573d6000803e3d6000fd5b50505050806001600160a01b0316846001600160a01b03167f3799680c99183658e109873f9f352e8f136e8ef04c1963b80064ff525c2d4d898560405162001c9891906200275f565b60405180910390a350600198975050505050505050565b600062001383838362001e3d565b600062001383836001600160a01b03841662001e86565b600062000eb38262001e9e565b600062001383836001600160a01b03841662001ea2565b600062001383836001600160a01b03841662001ef1565b600054610100900460ff168062001d2b575062001d2b62001806565b8062001d3a575060005460ff16155b62001d595760405162461bcd60e51b8152600401620005009062002b57565b600054610100900460ff16158015620018a3576000805460ff1961ff0019909116610100171660011790558015620018b6576000805461ff001916905550565b62001da362001fed565b600362001db18484620018b9565b600c81111562001dbd57fe5b1462001ddd5760405162461bcd60e51b8152600401620005009062002c24565b620013838284018462002636565b62001df56200200f565b600462001e038484620018b9565b600c81111562001e0f57fe5b1462001e2f5760405162461bcd60e51b8152600401620005009062002d53565b620013838284018462002534565b8154600090821062001e635760405162461bcd60e51b8152600401620005009062002882565b82600001828154811062001e7357fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b600062001eb0838362001e86565b62001ee85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000eb3565b50600062000eb3565b6000818152600183016020526040812054801562001fb2578354600019808301919081019060009087908390811062001f2657fe5b906000526020600020015490508087600001848154811062001f4457fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908062001f7557fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505062000eb3565b600091505062000eb3565b604051806080016040528062001fd26200204d565b81526000602082018190526040820181905260609091015290565b60405180604001604052806200200262001fbd565b8152602001600081525090565b60405180606001604052806200202462001fbd565b8152602001600081526020016200203a62002061565b905290565b6120668062002fdd83390190565b60408051602081019091528060006200203a565b604051806060016040528060608152602001600060ff168152602001606081525090565b60008083601f84011262002097578182fd5b50813567ffffffffffffffff811115620020af578182fd5b602083019150836020828501011115620020c857600080fd5b9250929050565b8035600d811062000eb357600080fd5b600082601f830112620020f0578081fd5b813567ffffffffffffffff81111562002107578182fd5b6200211c601f8201601f191660200162002f41565b91508082528360208285010111156200213457600080fd5b8060208401602084013760009082016020015292915050565b6000818303608081121562002160578182fd5b6200216c608062002f41565b915060208112156200217d57600080fd5b506200218a602062002f41565b620021968484620020cf565b815281526020820135620021aa8162002fc6565b60208201526040820135620021bf8162002fc6565b806040830152506060820135606082015292915050565b803560ff8116811462000eb357600080fd5b600060208284031215620021fa578081fd5b8135620013838162002fc6565b6000806000606084860312156200221c578182fd5b8335620022298162002fc6565b925060208401356200223b8162002fc6565b929592945050506040919091013590565b600080604083850312156200225f578182fd5b82356200226c8162002fc6565b915060208301356200227e8162002fc6565b809150509250929050565b6000602082840312156200229b578081fd5b8151801515811462001383578182fd5b600060208284031215620022bd578081fd5b5035919050565b60008060408385031215620022d7578182fd5b8235915060208301356200227e8162002fc6565b6000806000806060858703121562002301578182fd5b843593506020850135620023158162002fc6565b9250604085013567ffffffffffffffff81111562002331578283fd5b6200233f8782880162002085565b95989497509550505050565b600080604083850312156200235e578182fd5b50508035926020909101359150565b6000602082840312156200237f578081fd5b620013838383620020cf565b600080602083850312156200239e578182fd5b823567ffffffffffffffff811115620023b5578283fd5b620023c38582860162002085565b90969095509350505050565b600080600060408486031215620023e4578081fd5b833567ffffffffffffffff811115620023fb578182fd5b620024098682870162002085565b90945092505060208401356200241f8162002fc6565b809150509250925092565b60008060008060006080868803121562002442578283fd5b853567ffffffffffffffff81111562002459578384fd5b620024678882890162002085565b90965094505060208601356200247d8162002fc6565b925060408601356200248f8162002fc6565b949793965091946060013592915050565b600080600080600060a08688031215620024b8578283fd5b853567ffffffffffffffff811115620024cf578384fd5b620024dd88828901620020df565b9550506020860135620024f08162002fc6565b93506040860135620025028162002fc6565b92506060860135620025148162002fc6565b91506080860135620025268162002fc6565b809150509295509295909350565b60006020828403121562002546578081fd5b813567ffffffffffffffff808211156200255e578283fd5b9083019060c0828603121562002572578283fd5b6200257e606062002f41565b6200258a86846200214d565b81526080830135602082015260a083013582811115620025a8578485fd5b929092019160608387031215620025bd578384fd5b620025c9606062002f41565b833583811115620025d8578586fd5b620025e688828701620020df565b825250620025f88760208601620021d6565b60208201526040840135838111156200260f578586fd5b6200261d88828701620020df565b6040830152508060408301525080935050505092915050565b600060a0828403121562002648578081fd5b62002654604062002f41565b6200266084846200214d565b815260809290920135602083015250919050565b60006020828403121562002686578081fd5b5051919050565b60008151808452620026a781602086016020860162002f93565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b60008251620026df81846020870162002f93565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b60006060825284606083015284866080840137608085830181018290526001600160a01b0385166020840152601f8601601f191683018381038201604085015290620027b7908201856200268d565b979650505050505050565b6000602082526200138360208301846200268d565b600060608252620027ec60608301866200268d565b6001600160a01b038516602084015282810360408401526200280f81856200268d565b9695505050505050565b6000604082526200282e60408301856200268d565b82810360208401526200284281856200268d565b95945050505050565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260159082015274151bdd185b081cdd5c1c1b1e48195e18d959591959605a1b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526014908201527304661696c656420746f2073656e642045524332360641b604082015260600190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b602080825260129082015271496e73756666696369656e742066756e647360701b604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526017908201527f546f74616c537570706c79206973206e6f74207a65726f000000000000000000604082015260600190565b60208082526028908201527f5472616e73666572206973206e6f7420617070726f76656420627920746f6b6560408201526737103437b63232b960c11b606082015260800190565b60208082526033908201527f4d6573736167652074797065206973206e6f74204552433230207472616e7366604082015272657220616e6420746f74616c20737570706c7960681b606082015260800190565b6020808252601c908201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604082015260600190565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b60208082526032908201527f4d6573736167652074797065206973206e6f74204552433230207472616e73666040820152716572207769746820746f6b656e20696e666f60701b606082015260800190565b6020808252601e908201527f436f756c64206e6f74207472616e7366657220455243323020546f6b656e0000604082015260600190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b60208082526018908201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60208082526016908201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604082015260600190565b8151516080820190600d811062002f0b57fe5b80835250602083015160018060a01b03808216602085015280604086015116604085015250506060830151606083015292915050565b60405181810167ffffffffffffffff8111828210171562002f6157600080fd5b604052919050565b6000808585111562002f79578182fd5b8386111562002f86578182fd5b5050820193919092039150565b60005b8381101562002fb057818101518382015260200162002f96565b8381111562002fc0576000848401525b50505050565b6001600160a01b0381168114620018b657600080fdfe60806040523480156200001157600080fd5b506040516200206638038062002066833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604052505050620001b46200022760201b62000a681760201c565b620001cb8282620002e560201b62000b191760201c565b620001e06200022760201b62000a681760201c565b620001fb6000805160206200204683398151915280620003a7565b6200021f6000805160206200204683398151915262000219620003f9565b620003fd565b50506200075b565b600054610100900460ff1680620002435750620002436200040d565b8062000252575060005460ff16155b6200028f5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff16158015620002bb576000805460ff1961ff0019909116610100171660011790555b620002c56200042b565b620002cf6200042b565b8015620002e2576000805461ff00191690555b50565b600054610100900460ff1680620003015750620003016200040d565b8062000310575060005460ff16155b6200034d5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff1615801562000379576000805460ff1961ff0019909116610100171660011790555b620003836200042b565b6200038f8383620004d3565b8015620003a2576000805461ff00191690555b505050565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620004098282620005b7565b5050565b600062000425306200063260201b62000bce1760201c565b15905090565b600054610100900460ff1680620004475750620004476200040d565b8062000456575060005460ff16155b620004935760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff16158015620002cf576000805460ff1961ff0019909116610100171660011790558015620002e2576000805461ff001916905550565b600054610100900460ff1680620004ef5750620004ef6200040d565b80620004fe575060005460ff16155b6200053b5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff1615801562000567576000805460ff1961ff0019909116610100171660011790555b82516200057c906068906020860190620006bf565b50815162000592906069906020850190620006bf565b50606a805460ff191660121790558015620003a2576000805461ff0019169055505050565b6000828152603360209081526040909120620005de91839062000bd462000638821b17901c565b156200040957620005ee620003f9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b60006200064f836001600160a01b03841662000658565b90505b92915050565b6000620006668383620006a7565b6200069e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000652565b50600062000652565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200070257805160ff191683800117855562000732565b8280016001018555821562000732579182015b828111156200073257825182559160200191906001019062000715565b506200074092915062000744565b5090565b5b8082111562000740576000815560010162000745565b6118ad806200076b6000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d714610436578063a9059cbb14610462578063ca15c8731461048e578063d5391393146104ab578063d547741f146104b3578063dd62ed3e146104df5761014d565b806370a082311461036957806379cc67901461038f5780639010d07c146103bb57806391d14854146103fa57806395d89b4114610426578063a217fddf1461042e5761014d565b80632f2ff15d116101155780632f2ff15d1461027c578063313ce567146102aa57806336568abe146102c857806339509351146102f457806340c10f191461032057806342966c681461034c5761014d565b806306fdde0314610152578063095ea7b3146101cf57806318160ddd1461020f57806323b872dd14610229578063248a9ca31461025f575b600080fd5b61015a61050d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561019457818101518382015260200161017c565b50505050905090810190601f1680156101c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101fb600480360360408110156101e557600080fd5b506001600160a01b0381351690602001356105a3565b604080519115158252519081900360200190f35b6102176105c1565b60408051918252519081900360200190f35b6101fb6004803603606081101561023f57600080fd5b506001600160a01b038135811691602081013590911690604001356105c7565b6102176004803603602081101561027557600080fd5b503561064e565b6102a86004803603604081101561029257600080fd5b50803590602001356001600160a01b0316610663565b005b6102b26106cf565b6040805160ff9092168252519081900360200190f35b6102a8600480360360408110156102de57600080fd5b50803590602001356001600160a01b03166106d8565b6101fb6004803603604081101561030a57600080fd5b506001600160a01b038135169060200135610739565b6102a86004803603604081101561033657600080fd5b506001600160a01b038135169060200135610787565b6102a86004803603602081101561036257600080fd5b5035610807565b6102176004803603602081101561037f57600080fd5b50356001600160a01b031661081b565b6102a8600480360360408110156103a557600080fd5b506001600160a01b038135169060200135610836565b6103de600480360360408110156103d157600080fd5b5080359060200135610890565b604080516001600160a01b039092168252519081900360200190f35b6101fb6004803603604081101561041057600080fd5b50803590602001356001600160a01b03166108af565b61015a6108c7565b610217610928565b6101fb6004803603604081101561044c57600080fd5b506001600160a01b03813516906020013561092d565b6101fb6004803603604081101561047857600080fd5b506001600160a01b038135169060200135610995565b610217600480360360208110156104a457600080fd5b50356109a9565b6102176109c0565b6102a8600480360360408110156104c957600080fd5b50803590602001356001600160a01b03166109e4565b610217600480360360408110156104f557600080fd5b506001600160a01b0381358116916020013516610a3d565b60688054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b820191906000526020600020905b81548152906001019060200180831161057c57829003601f168201915b5050505050905090565b60006105b76105b0610be9565b8484610bed565b5060015b92915050565b60675490565b60006105d4848484610cd9565b610644846105e0610be9565b61063f8560405180606001604052806028815260200161176e602891396001600160a01b038a1660009081526066602052604081209061061e610be9565b6001600160a01b031681526020810191909152604001600020549190610e36565b610bed565b5060019392505050565b60009081526033602052604090206002015490565b60008281526033602052604090206002015461068690610681610be9565b6108af565b6106c15760405162461bcd60e51b815260040180806020018281038252602f815260200180611677602f913960400191505060405180910390fd5b6106cb8282610ecd565b5050565b606a5460ff1690565b6106e0610be9565b6001600160a01b0316816001600160a01b03161461072f5760405162461bcd60e51b815260040180806020018281038252602f815260200180611849602f913960400191505060405180910390fd5b6106cb8282610f36565b60006105b7610746610be9565b8461063f8560666000610757610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610f9f565b6107b37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610681610be9565b6107fd576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b6106cb8282610ff9565b610818610812610be9565b826110eb565b50565b6001600160a01b031660009081526065602052604090205490565b600061086d826040518060600160405280602481526020016117966024913961086686610861610be9565b610a3d565b9190610e36565b90506108818361087b610be9565b83610bed565b61088b83836110eb565b505050565b60008281526033602052604081206108a890836111e7565b9392505050565b60008281526033602052604081206108a890836111f3565b60698054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b600081565b60006105b761093a610be9565b8461063f856040518060600160405280602581526020016118246025913960666000610964610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610e36565b60006105b76109a2610be9565b8484610cd9565b60008181526033602052604081206105bb90611208565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b600082815260336020526040902060020154610a0290610681610be9565b61072f5760405162461bcd60e51b81526004018080602001828103825260308152602001806117106030913960400191505060405180910390fd5b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b600054610100900460ff1680610a815750610a81611213565b80610a8f575060005460ff16155b610aca5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610af5576000805460ff1961ff0019909116610100171660011790555b610afd611224565b610b05611224565b8015610818576000805461ff001916905550565b600054610100900460ff1680610b325750610b32611213565b80610b40575060005460ff16155b610b7b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610ba6576000805460ff1961ff0019909116610100171660011790555b610bae611224565b610bb883836112c4565b801561088b576000805461ff0019169055505050565b3b151590565b60006108a8836001600160a01b03841661139c565b3390565b6001600160a01b038316610c325760405162461bcd60e51b81526004018080602001828103825260248152602001806118006024913960400191505060405180910390fd5b6001600160a01b038216610c775760405162461bcd60e51b81526004018080602001828103825260228152602001806116c86022913960400191505060405180910390fd5b6001600160a01b03808416600081815260666020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610d1e5760405162461bcd60e51b81526004018080602001828103825260258152602001806117db6025913960400191505060405180910390fd5b6001600160a01b038216610d635760405162461bcd60e51b81526004018080602001828103825260238152602001806116546023913960400191505060405180910390fd5b610d6e83838361088b565b610dab816040518060600160405280602681526020016116ea602691396001600160a01b0386166000908152606560205260409020549190610e36565b6001600160a01b038085166000908152606560205260408082209390935590841681522054610dda9082610f9f565b6001600160a01b0380841660008181526065602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610ec55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610e8a578181015183820152602001610e72565b50505050905090810190601f168015610eb75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828152603360205260409020610ee59082610bd4565b156106cb57610ef2610be9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020610f4e90826113e6565b156106cb57610f5b610be9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000828201838110156108a8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216611054576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6110606000838361088b565b60675461106d9082610f9f565b6067556001600160a01b0382166000908152606560205260409020546110939082610f9f565b6001600160a01b03831660008181526065602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b0382166111305760405162461bcd60e51b81526004018080602001828103825260218152602001806117ba6021913960400191505060405180910390fd5b61113c8260008361088b565b611179816040518060600160405280602281526020016116a6602291396001600160a01b0385166000908152606560205260409020549190610e36565b6001600160a01b03831660009081526065602052604090205560675461119f90826113fb565b6067556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60006108a88383611458565b60006108a8836001600160a01b0384166114bc565b60006105bb826114d4565b600061121e30610bce565b15905090565b600054610100900460ff168061123d575061123d611213565b8061124b575060005460ff16155b6112865760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610b05576000805460ff1961ff0019909116610100171660011790558015610818576000805461ff001916905550565b600054610100900460ff16806112dd57506112dd611213565b806112eb575060005460ff16155b6113265760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015611351576000805460ff1961ff0019909116610100171660011790555b825161136490606890602086019061159e565b50815161137890606990602085019061159e565b50606a805460ff19166012179055801561088b576000805461ff0019169055505050565b60006113a883836114bc565b6113de575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bb565b5060006105bb565b60006108a8836001600160a01b0384166114d8565b600082821115611452576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b8154600090821061149a5760405162461bcd60e51b81526004018080602001828103825260228152602001806116326022913960400191505060405180910390fd5b8260000182815481106114a957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60008181526001830160205260408120548015611594578354600019808301919081019060009087908390811061150b57fe5b906000526020600020015490508087600001848154811061152857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061155857fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506105bb565b60009150506105bb565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106115df57805160ff191683800117855561160c565b8280016001018555821561160c579182015b8281111561160c5782518255916020019190600101906115f1565b5061161892915061161c565b5090565b5b80821115611618576000815560010161161d56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7445524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220f5fd5b9f427fa0188f9574676da4de58e3fd195487cc5f2ba14cd5cbd4d68d2464736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220fe207ed89cc17d38d8f034964b3e08743099bc2cf9e6a046aed52f29ac1f19c564736f6c634300060c0033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200022c5760003560e01c80635573b8b61162000135578063b9581c5011620000bd578063cc5b715b1162000087578063cc5b715b146200046d578063d547741f1462000477578063dec2deb6146200048e578063edcc12b51462000498578063f429e38314620004af576200022c565b8063b9581c50146200041e578063c0e312dc1462000428578063ca15c873146200043f578063cb703bff1462000456576200022c565b8063884cee5a11620000ff578063884cee5a14620003cf5780639010d07c14620003e657806391d1485414620003fd578063a217fddf1462000414576200022c565b80635573b8b6146200039a5780636ce681d214620003a45780636d61128614620003bb5780636d6c68e614620003c5576200022c565b80632dc151de11620001b95780633b690b6b11620001835780633b690b6b14620003565780633fa194ce14620003605780634d58c889146200036a57806350f442801462000381576200022c565b80632dc151de14620002f85780632f2ff15d146200030257806336568abe146200031957806339927cf91462000330576200022c565b8063248a9ca311620001fb578063248a9ca3146200029a57806328c5e18214620002c05780632baaf64314620002ca5780632d6eea0614620002e1576200022c565b8063029996b814620002315780630472e00a146200023d5780630b885ac314620002545780630f1a8f74146200026b575b600080fd5b6200023b620004c6565b005b6200023b6200024e3660046200242a565b6200051e565b6200023b62000265366004620024a0565b6200093d565b620002826200027c366004620022ab565b62000953565b604051620002919190620026e9565b60405180910390f35b620002b1620002ab366004620022ab565b6200096e565b6040516200029191906200275f565b620002b162000983565b6200023b620002db36600462002207565b620009ce565b62000282620002f2366004620021e8565b62000d97565b6200028262000db2565b6200023b62000313366004620022c4565b62000dc1565b6200023b6200032a366004620022c4565b62000e11565b62000347620003413660046200238b565b62000e5a565b60405162000291919062002754565b620002b162000eb9565b620002b162000ebf565b6200023b6200037b3660046200224c565b62000ed2565b6200038b6200103c565b604051620002919190620027c2565b620002826200105f565b6200023b620003b5366004620024a0565b6200106e565b62000282620011d5565b62000282620011e4565b62000347620003e0366004620022eb565b620011f3565b62000282620003f73660046200234b565b62001369565b620003476200040e366004620022c4565b6200138a565b620002b1620013a4565b6200023b620013a9565b6200023b620004393660046200238b565b620013f2565b620002b162000450366004620022ab565b620014ba565b6200023b62000467366004620023cf565b620014d3565b620002b1620015d5565b6200023b62000488366004620022c4565b620015f9565b6200034762001639565b6200023b620004a9366004620021e8565b62001649565b620002b1620004c0366004620021e8565b62001697565b620004e160008051602062005043833981519152336200138a565b620005095760405162461bcd60e51b8152600401620005009062002a65565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b6001600160a01b038216620005475760405162461bcd60e51b8152600401620005009062002cae565b600085856040516020016200055e929190620026bb565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b848301529151919350620005a0929101620026cb565b60405160208183030381529060405280519060200120811415620005d85760405162461bcd60e51b81526004016200050090620029b0565b6000818152606a60205260409020546001600160a01b03166200060f5760405162461bcd60e51b815260040162000500906200284b565b6001600160a01b038085166000908152606b6020526040902054166200063581620016a9565b620006545760405162461bcd60e51b8152600401620005009062002e42565b6040516370a0823160e01b815283906001600160a01b038316906370a082319062000684903390600401620026e9565b60206040518083038186803b1580156200069d57600080fd5b505afa158015620006b2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006d8919062002674565b1015620006f95760405162461bcd60e51b8152600401620005009062002aa6565b604051636eb1769f60e11b815283906001600160a01b0383169063dd62ed3e906200072b9033903090600401620026fd565b60206040518083038186803b1580156200074457600080fd5b505afa15801562000759573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200077f919062002674565b1015620007a05760405162461bcd60e51b8152600401620005009062002bdc565b6040516323b872dd60e01b81526001600160a01b038216906323b872dd90620007d29033903090889060040162002717565b602060405180830381600087803b158015620007ed57600080fd5b505af115801562000802573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000828919062002289565b620008475760405162461bcd60e51b8152600401620005009062002da5565b604051630852cd8d60e31b81526001600160a01b038216906342966c6890620008759086906004016200275f565b600060405180830381600087803b1580156200089057600080fd5b505af1158015620008a5573d6000803e3d6000fd5b50506065546000858152606a60205260409020546001600160a01b0391821693506365e3781f92508a918a9116620008df8a8a8a620016af565b6040518563ffffffff1660e01b815260040162000900949392919062002768565b600060405180830381600087803b1580156200091b57600080fd5b505af115801562000930573d6000803e3d6000fd5b5050505050505050505050565b6200094c85858585856200106e565b5050505050565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009b59190620026cb565b6040516020818303038152906040528051906020012081565b6001600160a01b038216620009f75760405162461bcd60e51b8152600401620005009062002cae565b6067546040516311be333d60e11b81526001600160a01b039091169063237c667a9062000a29908590600401620026e9565b600060405180830381600087803b15801562000a4457600080fd5b505af115801562000a59573d6000803e3d6000fd5b505050506001600160a01b038381166000908152606b60205260409020541662000a8381620016a9565b62000aa25760405162461bcd60e51b8152600401620005009062002e42565b6040516370a0823160e01b815282906001600160a01b038316906370a082319062000ad2903390600401620026e9565b60206040518083038186803b15801562000aeb57600080fd5b505afa15801562000b00573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b26919062002674565b101562000b475760405162461bcd60e51b8152600401620005009062002aa6565b604051636eb1769f60e11b815282906001600160a01b0383169063dd62ed3e9062000b799033903090600401620026fd565b60206040518083038186803b15801562000b9257600080fd5b505afa15801562000ba7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bcd919062002674565b101562000bee5760405162461bcd60e51b8152600401620005009062002bdc565b6040516323b872dd60e01b81526001600160a01b038216906323b872dd9062000c209033903090879060040162002717565b602060405180830381600087803b15801562000c3b57600080fd5b505af115801562000c50573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c76919062002289565b62000c955760405162461bcd60e51b8152600401620005009062002da5565b604051630852cd8d60e31b81526001600160a01b038216906342966c689062000cc39085906004016200275f565b600060405180830381600087803b15801562000cde57600080fd5b505af115801562000cf3573d6000803e3d6000fd5b505060655460408051808201909152600781526613585a5b9b995d60ca1b60208201526069546001600160a01b0392831694506365e3781f935090911662000d3d888888620016af565b6040518463ffffffff1660e01b815260040162000d5d93929190620027d7565b600060405180830381600087803b15801562000d7857600080fd5b505af115801562000d8d573d6000803e3d6000fd5b5050505050505050565b606b602052600090815260409020546001600160a01b031681565b6066546001600160a01b031681565b60008281526033602052604090206002015462000de2906200040e62001726565b62000e015760405162461bcd60e51b81526004016200050090620028f3565b62000e0d82826200172a565b5050565b62000e1b62001726565b6001600160a01b0316816001600160a01b03161462000e4e5760405162461bcd60e51b8152600401620005009062002e79565b62000e0d828262001798565b6000806001600160a01b0316606a6000858560405160200162000e7f929190620026bb565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b60685481565b6000805160206200504383398151915281565b62000efe7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba8336200138a565b62000f1d5760405162461bcd60e51b8152600401620005009062002b22565b62000f31816001600160a01b0316620016a9565b62000f505760405162461bcd60e51b8152600401620005009062002ce5565b806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000f8a57600080fd5b505afa15801562000f9f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fc5919062002674565b1562000fe55760405162461bcd60e51b8152600401620005009062002ba5565b6001600160a01b038281166000818152606b602052604080822080546001600160a01b0319169486169485179055517fc6e93524baaa4770b94da082aa0caeac9ba78c87f7edc7c3d2820f2e9fdf400a9190a35050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b600054610100900460ff16806200108a57506200108a62001806565b8062001099575060005460ff16155b620010b85760405162461bcd60e51b8152600401620005009062002b57565b600054610100900460ff16158015620010e4576000805460ff1961ff0019909116610100171660011790555b620010ee62001819565b620010fb60003362000e01565b62001116600080516020620050438339815191523362000e01565b620011427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362000e01565b85604051602001620011559190620026cb565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b031992831617909255606680548784169083161790556067805486841690831617905560698054928516929091169190911790558015620011cd576000805461ff00191690555b505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b6065546000906001600160a01b03163314620012235760405162461bcd60e51b8152600401620005009062002942565b6068548514158015620012b557506040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620012639190620026cb565b604051602081830303815290604052805190602001208514620012a3576000858152606a60205260409020546001600160a01b03858116911614620012b5565b6069546001600160a01b038581169116145b620012d45760405162461bcd60e51b8152600401620005009062002d1c565b6000620012e28484620018b9565b9050600481600c811115620012f357fe5b14806200130c5750600381600c8111156200130a57fe5b145b1562001343576200131e848462001904565b6200133d5760405162461bcd60e51b8152600401620005009062002a37565b6200135d565b60405162461bcd60e51b8152600401620005009062002ec8565b50600195945050505050565b600082815260336020526040812062001383908362001caf565b9392505050565b600082815260336020526040812062001383908362001cbd565b600081565b620013c460008051602062005043833981519152336200138a565b620013e35760405162461bcd60e51b8152600401620005009062002a65565b6069805460ff60a01b19169055565b6066546001600160a01b0316331480620014145750620014146000336200138a565b620014335760405162461bcd60e51b8152600401620005009062002e13565b600082826040516020016200144a929190620026bb565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b03166200149a5760405162461bcd60e51b8152600401620005009062002a00565b6000908152606a6020526040902080546001600160a01b03191690555050565b600081815260336020526040812062000eb39062001cd4565b6066546001600160a01b0316331480620014f55750620014f56000336200138a565b620015145760405162461bcd60e51b8152600401620005009062002e13565b600083836040516020016200152b929190620026bb565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b0316156200157c5760405162461bcd60e51b8152600401620005009062002ddc565b6001600160a01b038216620015a55760405162461bcd60e51b815260040162000500906200284b565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b6000828152603360205260409020600201546200161a906200040e62001726565b62000e4e5760405162461bcd60e51b8152600401620005009062002ad2565b606954600160a01b900460ff1681565b620016566000336200138a565b620016755760405162461bcd60e51b8152600401620005009062002979565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b606c6020526000908152604090205481565b3b151590565b6060620016bb62001fbd565b6040805160a0810190915280608081018060028152508152602001866001600160a01b03168152602001856001600160a01b03168152602001848152509050806040516020016200170d919062002ef8565b6040516020818303038152906040529150509392505050565b3390565b600082815260336020526040902062001744908262001ce1565b1562000e0d576200175462001726565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020620017b2908262001cf8565b1562000e0d57620017c262001726565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60006200181330620016a9565b15905090565b600054610100900460ff16806200183557506200183562001806565b8062001844575060005460ff16155b620018635760405162461bcd60e51b8152600401620005009062002b57565b600054610100900460ff161580156200188f576000805460ff1961ff0019909116610100171660011790555b6200189962001d0f565b620018a362001d0f565b8015620018b6576000805461ff00191690555b50565b600080620018ca83850185620022ab565b905060208106620018f657620018ed620018e78483818862002f69565b620018b9565b91505062000eb3565b620018ed838501856200236d565b600080620019138484620018b9565b9050600080808080600386600c8111156200192a57fe5b141562001990576200193b62001fed565b620019478a8a62001d99565b8051604080820151602080840151606090940151948101516001600160a01b038086166000908152606b9093529390912054919a5092985092965090945016915062001ac29050565b6200199a6200200f565b620019a68a8a62001deb565b8051604080820151602080840151606090940151818601516001600160a01b038087166000908152606b9094529490922054929b5093995092975091955016925090508162001ac057606954600160a01b900460ff1662001a1b5760405162461bcd60e51b8152600401620005009062002c77565b80604001516000015181604001516040015160405162001a3b906200203f565b62001a4892919062002819565b604051809103906000f08015801562001a65573d6000803e3d6000fd5b506001600160a01b038681166000818152606b602052604080822080546001600160a01b031916948616948517905551939550919290917fcdae5f6ddbda7847ad809fcd087e35946ef42729ff7ecdbcc81a03eb3a52ab2891a35b505b62001ad6816001600160a01b0316620016a9565b62001af55760405162461bcd60e51b8152600401620005009062002ce5565b6001600160a01b0381166000908152606c6020526040902054821462001b31576001600160a01b0381166000908152606c602052604090208290555b606c6000826001600160a01b03166001600160a01b031681526020019081526020016000205483826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562001b9257600080fd5b505afa15801562001ba7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bcd919062002674565b01111562001bef5760405162461bcd60e51b81526004016200050090620028c4565b6040516340c10f1960e01b81526001600160a01b038216906340c10f199062001c1f90889087906004016200273b565b600060405180830381600087803b15801562001c3a57600080fd5b505af115801562001c4f573d6000803e3d6000fd5b50505050806001600160a01b0316846001600160a01b03167f3799680c99183658e109873f9f352e8f136e8ef04c1963b80064ff525c2d4d898560405162001c9891906200275f565b60405180910390a350600198975050505050505050565b600062001383838362001e3d565b600062001383836001600160a01b03841662001e86565b600062000eb38262001e9e565b600062001383836001600160a01b03841662001ea2565b600062001383836001600160a01b03841662001ef1565b600054610100900460ff168062001d2b575062001d2b62001806565b8062001d3a575060005460ff16155b62001d595760405162461bcd60e51b8152600401620005009062002b57565b600054610100900460ff16158015620018a3576000805460ff1961ff0019909116610100171660011790558015620018b6576000805461ff001916905550565b62001da362001fed565b600362001db18484620018b9565b600c81111562001dbd57fe5b1462001ddd5760405162461bcd60e51b8152600401620005009062002c24565b620013838284018462002636565b62001df56200200f565b600462001e038484620018b9565b600c81111562001e0f57fe5b1462001e2f5760405162461bcd60e51b8152600401620005009062002d53565b620013838284018462002534565b8154600090821062001e635760405162461bcd60e51b8152600401620005009062002882565b82600001828154811062001e7357fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b600062001eb0838362001e86565b62001ee85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000eb3565b50600062000eb3565b6000818152600183016020526040812054801562001fb2578354600019808301919081019060009087908390811062001f2657fe5b906000526020600020015490508087600001848154811062001f4457fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908062001f7557fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505062000eb3565b600091505062000eb3565b604051806080016040528062001fd26200204d565b81526000602082018190526040820181905260609091015290565b60405180604001604052806200200262001fbd565b8152602001600081525090565b60405180606001604052806200202462001fbd565b8152602001600081526020016200203a62002061565b905290565b6120668062002fdd83390190565b60408051602081019091528060006200203a565b604051806060016040528060608152602001600060ff168152602001606081525090565b60008083601f84011262002097578182fd5b50813567ffffffffffffffff811115620020af578182fd5b602083019150836020828501011115620020c857600080fd5b9250929050565b8035600d811062000eb357600080fd5b600082601f830112620020f0578081fd5b813567ffffffffffffffff81111562002107578182fd5b6200211c601f8201601f191660200162002f41565b91508082528360208285010111156200213457600080fd5b8060208401602084013760009082016020015292915050565b6000818303608081121562002160578182fd5b6200216c608062002f41565b915060208112156200217d57600080fd5b506200218a602062002f41565b620021968484620020cf565b815281526020820135620021aa8162002fc6565b60208201526040820135620021bf8162002fc6565b806040830152506060820135606082015292915050565b803560ff8116811462000eb357600080fd5b600060208284031215620021fa578081fd5b8135620013838162002fc6565b6000806000606084860312156200221c578182fd5b8335620022298162002fc6565b925060208401356200223b8162002fc6565b929592945050506040919091013590565b600080604083850312156200225f578182fd5b82356200226c8162002fc6565b915060208301356200227e8162002fc6565b809150509250929050565b6000602082840312156200229b578081fd5b8151801515811462001383578182fd5b600060208284031215620022bd578081fd5b5035919050565b60008060408385031215620022d7578182fd5b8235915060208301356200227e8162002fc6565b6000806000806060858703121562002301578182fd5b843593506020850135620023158162002fc6565b9250604085013567ffffffffffffffff81111562002331578283fd5b6200233f8782880162002085565b95989497509550505050565b600080604083850312156200235e578182fd5b50508035926020909101359150565b6000602082840312156200237f578081fd5b620013838383620020cf565b600080602083850312156200239e578182fd5b823567ffffffffffffffff811115620023b5578283fd5b620023c38582860162002085565b90969095509350505050565b600080600060408486031215620023e4578081fd5b833567ffffffffffffffff811115620023fb578182fd5b620024098682870162002085565b90945092505060208401356200241f8162002fc6565b809150509250925092565b60008060008060006080868803121562002442578283fd5b853567ffffffffffffffff81111562002459578384fd5b620024678882890162002085565b90965094505060208601356200247d8162002fc6565b925060408601356200248f8162002fc6565b949793965091946060013592915050565b600080600080600060a08688031215620024b8578283fd5b853567ffffffffffffffff811115620024cf578384fd5b620024dd88828901620020df565b9550506020860135620024f08162002fc6565b93506040860135620025028162002fc6565b92506060860135620025148162002fc6565b91506080860135620025268162002fc6565b809150509295509295909350565b60006020828403121562002546578081fd5b813567ffffffffffffffff808211156200255e578283fd5b9083019060c0828603121562002572578283fd5b6200257e606062002f41565b6200258a86846200214d565b81526080830135602082015260a083013582811115620025a8578485fd5b929092019160608387031215620025bd578384fd5b620025c9606062002f41565b833583811115620025d8578586fd5b620025e688828701620020df565b825250620025f88760208601620021d6565b60208201526040840135838111156200260f578586fd5b6200261d88828701620020df565b6040830152508060408301525080935050505092915050565b600060a0828403121562002648578081fd5b62002654604062002f41565b6200266084846200214d565b815260809290920135602083015250919050565b60006020828403121562002686578081fd5b5051919050565b60008151808452620026a781602086016020860162002f93565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b60008251620026df81846020870162002f93565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b60006060825284606083015284866080840137608085830181018290526001600160a01b0385166020840152601f8601601f191683018381038201604085015290620027b7908201856200268d565b979650505050505050565b6000602082526200138360208301846200268d565b600060608252620027ec60608301866200268d565b6001600160a01b038516602084015282810360408401526200280f81856200268d565b9695505050505050565b6000604082526200282e60408301856200268d565b82810360208401526200284281856200268d565b95945050505050565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260159082015274151bdd185b081cdd5c1c1b1e48195e18d959591959605a1b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526014908201527304661696c656420746f2073656e642045524332360641b604082015260600190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b602080825260129082015271496e73756666696369656e742066756e647360701b604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526017908201527f546f74616c537570706c79206973206e6f74207a65726f000000000000000000604082015260600190565b60208082526028908201527f5472616e73666572206973206e6f7420617070726f76656420627920746f6b6560408201526737103437b63232b960c11b606082015260800190565b60208082526033908201527f4d6573736167652074797065206973206e6f74204552433230207472616e7366604082015272657220616e6420746f74616c20737570706c7960681b606082015260800190565b6020808252601c908201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604082015260600190565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b60208082526032908201527f4d6573736167652074797065206973206e6f74204552433230207472616e73666040820152716572207769746820746f6b656e20696e666f60701b606082015260800190565b6020808252601e908201527f436f756c64206e6f74207472616e7366657220455243323020546f6b656e0000604082015260600190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b60208082526018908201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60208082526016908201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604082015260600190565b8151516080820190600d811062002f0b57fe5b80835250602083015160018060a01b03808216602085015280604086015116604085015250506060830151606083015292915050565b60405181810167ffffffffffffffff8111828210171562002f6157600080fd5b604052919050565b6000808585111562002f79578182fd5b8386111562002f86578182fd5b5050820193919092039150565b60005b8381101562002fb057818101518382015260200162002f96565b8381111562002fc0576000848401525b50505050565b6001600160a01b0381168114620018b657600080fdfe60806040523480156200001157600080fd5b506040516200206638038062002066833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604052505050620001b46200022760201b62000a681760201c565b620001cb8282620002e560201b62000b191760201c565b620001e06200022760201b62000a681760201c565b620001fb6000805160206200204683398151915280620003a7565b6200021f6000805160206200204683398151915262000219620003f9565b620003fd565b50506200075b565b600054610100900460ff1680620002435750620002436200040d565b8062000252575060005460ff16155b6200028f5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff16158015620002bb576000805460ff1961ff0019909116610100171660011790555b620002c56200042b565b620002cf6200042b565b8015620002e2576000805461ff00191690555b50565b600054610100900460ff1680620003015750620003016200040d565b8062000310575060005460ff16155b6200034d5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff1615801562000379576000805460ff1961ff0019909116610100171660011790555b620003836200042b565b6200038f8383620004d3565b8015620003a2576000805461ff00191690555b505050565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620004098282620005b7565b5050565b600062000425306200063260201b62000bce1760201c565b15905090565b600054610100900460ff1680620004475750620004476200040d565b8062000456575060005460ff16155b620004935760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff16158015620002cf576000805460ff1961ff0019909116610100171660011790558015620002e2576000805461ff001916905550565b600054610100900460ff1680620004ef5750620004ef6200040d565b80620004fe575060005460ff16155b6200053b5760405162461bcd60e51b815260040180806020018281038252602e81526020018062002018602e913960400191505060405180910390fd5b600054610100900460ff1615801562000567576000805460ff1961ff0019909116610100171660011790555b82516200057c906068906020860190620006bf565b50815162000592906069906020850190620006bf565b50606a805460ff191660121790558015620003a2576000805461ff0019169055505050565b6000828152603360209081526040909120620005de91839062000bd462000638821b17901c565b156200040957620005ee620003f9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b60006200064f836001600160a01b03841662000658565b90505b92915050565b6000620006668383620006a7565b6200069e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000652565b50600062000652565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200070257805160ff191683800117855562000732565b8280016001018555821562000732579182015b828111156200073257825182559160200191906001019062000715565b506200074092915062000744565b5090565b5b8082111562000740576000815560010162000745565b6118ad806200076b6000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d714610436578063a9059cbb14610462578063ca15c8731461048e578063d5391393146104ab578063d547741f146104b3578063dd62ed3e146104df5761014d565b806370a082311461036957806379cc67901461038f5780639010d07c146103bb57806391d14854146103fa57806395d89b4114610426578063a217fddf1461042e5761014d565b80632f2ff15d116101155780632f2ff15d1461027c578063313ce567146102aa57806336568abe146102c857806339509351146102f457806340c10f191461032057806342966c681461034c5761014d565b806306fdde0314610152578063095ea7b3146101cf57806318160ddd1461020f57806323b872dd14610229578063248a9ca31461025f575b600080fd5b61015a61050d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561019457818101518382015260200161017c565b50505050905090810190601f1680156101c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101fb600480360360408110156101e557600080fd5b506001600160a01b0381351690602001356105a3565b604080519115158252519081900360200190f35b6102176105c1565b60408051918252519081900360200190f35b6101fb6004803603606081101561023f57600080fd5b506001600160a01b038135811691602081013590911690604001356105c7565b6102176004803603602081101561027557600080fd5b503561064e565b6102a86004803603604081101561029257600080fd5b50803590602001356001600160a01b0316610663565b005b6102b26106cf565b6040805160ff9092168252519081900360200190f35b6102a8600480360360408110156102de57600080fd5b50803590602001356001600160a01b03166106d8565b6101fb6004803603604081101561030a57600080fd5b506001600160a01b038135169060200135610739565b6102a86004803603604081101561033657600080fd5b506001600160a01b038135169060200135610787565b6102a86004803603602081101561036257600080fd5b5035610807565b6102176004803603602081101561037f57600080fd5b50356001600160a01b031661081b565b6102a8600480360360408110156103a557600080fd5b506001600160a01b038135169060200135610836565b6103de600480360360408110156103d157600080fd5b5080359060200135610890565b604080516001600160a01b039092168252519081900360200190f35b6101fb6004803603604081101561041057600080fd5b50803590602001356001600160a01b03166108af565b61015a6108c7565b610217610928565b6101fb6004803603604081101561044c57600080fd5b506001600160a01b03813516906020013561092d565b6101fb6004803603604081101561047857600080fd5b506001600160a01b038135169060200135610995565b610217600480360360208110156104a457600080fd5b50356109a9565b6102176109c0565b6102a8600480360360408110156104c957600080fd5b50803590602001356001600160a01b03166109e4565b610217600480360360408110156104f557600080fd5b506001600160a01b0381358116916020013516610a3d565b60688054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b820191906000526020600020905b81548152906001019060200180831161057c57829003601f168201915b5050505050905090565b60006105b76105b0610be9565b8484610bed565b5060015b92915050565b60675490565b60006105d4848484610cd9565b610644846105e0610be9565b61063f8560405180606001604052806028815260200161176e602891396001600160a01b038a1660009081526066602052604081209061061e610be9565b6001600160a01b031681526020810191909152604001600020549190610e36565b610bed565b5060019392505050565b60009081526033602052604090206002015490565b60008281526033602052604090206002015461068690610681610be9565b6108af565b6106c15760405162461bcd60e51b815260040180806020018281038252602f815260200180611677602f913960400191505060405180910390fd5b6106cb8282610ecd565b5050565b606a5460ff1690565b6106e0610be9565b6001600160a01b0316816001600160a01b03161461072f5760405162461bcd60e51b815260040180806020018281038252602f815260200180611849602f913960400191505060405180910390fd5b6106cb8282610f36565b60006105b7610746610be9565b8461063f8560666000610757610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610f9f565b6107b37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610681610be9565b6107fd576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b6106cb8282610ff9565b610818610812610be9565b826110eb565b50565b6001600160a01b031660009081526065602052604090205490565b600061086d826040518060600160405280602481526020016117966024913961086686610861610be9565b610a3d565b9190610e36565b90506108818361087b610be9565b83610bed565b61088b83836110eb565b505050565b60008281526033602052604081206108a890836111e7565b9392505050565b60008281526033602052604081206108a890836111f3565b60698054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105995780601f1061056e57610100808354040283529160200191610599565b600081565b60006105b761093a610be9565b8461063f856040518060600160405280602581526020016118246025913960666000610964610be9565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610e36565b60006105b76109a2610be9565b8484610cd9565b60008181526033602052604081206105bb90611208565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b600082815260336020526040902060020154610a0290610681610be9565b61072f5760405162461bcd60e51b81526004018080602001828103825260308152602001806117106030913960400191505060405180910390fd5b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b600054610100900460ff1680610a815750610a81611213565b80610a8f575060005460ff16155b610aca5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610af5576000805460ff1961ff0019909116610100171660011790555b610afd611224565b610b05611224565b8015610818576000805461ff001916905550565b600054610100900460ff1680610b325750610b32611213565b80610b40575060005460ff16155b610b7b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610ba6576000805460ff1961ff0019909116610100171660011790555b610bae611224565b610bb883836112c4565b801561088b576000805461ff0019169055505050565b3b151590565b60006108a8836001600160a01b03841661139c565b3390565b6001600160a01b038316610c325760405162461bcd60e51b81526004018080602001828103825260248152602001806118006024913960400191505060405180910390fd5b6001600160a01b038216610c775760405162461bcd60e51b81526004018080602001828103825260228152602001806116c86022913960400191505060405180910390fd5b6001600160a01b03808416600081815260666020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038316610d1e5760405162461bcd60e51b81526004018080602001828103825260258152602001806117db6025913960400191505060405180910390fd5b6001600160a01b038216610d635760405162461bcd60e51b81526004018080602001828103825260238152602001806116546023913960400191505060405180910390fd5b610d6e83838361088b565b610dab816040518060600160405280602681526020016116ea602691396001600160a01b0386166000908152606560205260409020549190610e36565b6001600160a01b038085166000908152606560205260408082209390935590841681522054610dda9082610f9f565b6001600160a01b0380841660008181526065602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610ec55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610e8a578181015183820152602001610e72565b50505050905090810190601f168015610eb75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828152603360205260409020610ee59082610bd4565b156106cb57610ef2610be9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020610f4e90826113e6565b156106cb57610f5b610be9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000828201838110156108a8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216611054576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6110606000838361088b565b60675461106d9082610f9f565b6067556001600160a01b0382166000908152606560205260409020546110939082610f9f565b6001600160a01b03831660008181526065602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b0382166111305760405162461bcd60e51b81526004018080602001828103825260218152602001806117ba6021913960400191505060405180910390fd5b61113c8260008361088b565b611179816040518060600160405280602281526020016116a6602291396001600160a01b0385166000908152606560205260409020549190610e36565b6001600160a01b03831660009081526065602052604090205560675461119f90826113fb565b6067556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60006108a88383611458565b60006108a8836001600160a01b0384166114bc565b60006105bb826114d4565b600061121e30610bce565b15905090565b600054610100900460ff168061123d575061123d611213565b8061124b575060005460ff16155b6112865760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015610b05576000805460ff1961ff0019909116610100171660011790558015610818576000805461ff001916905550565b600054610100900460ff16806112dd57506112dd611213565b806112eb575060005460ff16155b6113265760405162461bcd60e51b815260040180806020018281038252602e815260200180611740602e913960400191505060405180910390fd5b600054610100900460ff16158015611351576000805460ff1961ff0019909116610100171660011790555b825161136490606890602086019061159e565b50815161137890606990602085019061159e565b50606a805460ff19166012179055801561088b576000805461ff0019169055505050565b60006113a883836114bc565b6113de575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105bb565b5060006105bb565b60006108a8836001600160a01b0384166114d8565b600082821115611452576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b8154600090821061149a5760405162461bcd60e51b81526004018080602001828103825260228152602001806116326022913960400191505060405180910390fd5b8260000182815481106114a957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60008181526001830160205260408120548015611594578354600019808301919081019060009087908390811061150b57fe5b906000526020600020015490508087600001848154811061152857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061155857fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506105bb565b60009150506105bb565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106115df57805160ff191683800117855561160c565b8280016001018555821561160c579182015b8281111561160c5782518255916020019190600101906115f1565b5061161892915061161c565b5090565b5b80821115611618576000815560010161161d56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e7445524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e20616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220f5fd5b9f427fa0188f9574676da4de58e3fd195487cc5f2ba14cd5cbd4d68d2464736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220fe207ed89cc17d38d8f034964b3e08743099bc2cf9e6a046aed52f29ac1f19c564736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC721.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC721.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC721.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC721.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC721.json new file mode 100644 index 000000000..2dbe1fd77 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerERC721.json @@ -0,0 +1,711 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerERC721", + "sourceName": "contracts/schain/TokenManagers/TokenManagerERC721.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "ERC721TokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "ERC721TokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721TokenReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "erc721OnMainnet", + "type": "address" + }, + { + "internalType": "contract ERC721OnChain", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "addERC721TokenByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "clonesErc721", + "outputs": [ + { + "internalType": "contract ERC721OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract CommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "exitToMainERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract MessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract TokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferToSchainERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50615c98806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620002205760003560e01c80636d6112861162000129578063b9581c5011620000b1578063cc5b715b116200007b578063cc5b715b1462000461578063d547741f146200046b578063dec2deb61462000482578063edcc12b5146200048c5762000220565b8063b9581c501462000412578063c0e312dc146200041c578063ca15c8731462000433578063cb703bff146200044a5762000220565b80638a8fe42111620000f35780638a8fe42114620003c35780639010d07c14620003da57806391d1485414620003f1578063a217fddf14620004085762000220565b80636d61128614620003815780636d6c68e6146200038b5780637b69620f1462000395578063884cee5a14620003ac5762000220565b806336568abe11620001ad5780633fa194ce11620001775780633fa194ce146200033d57806350f4428014620003475780635573b8b614620003605780636ce681d2146200036a5762000220565b806336568abe14620002df57806339927cf914620002f65780633b4612c1146200031c5780633b690b6b14620003335762000220565b806328c5e18211620001ef57806328c5e182146200029d5780632dc151de14620002a75780632f2ff15d14620002b157806330d86b2a14620002c85762000220565b8063029996b814620002255780630b885ac314620002315780630f1a8f741462000248578063248a9ca31462000277575b600080fd5b6200022f620004a3565b005b6200022f6200024236600462001ea3565b620004fb565b6200025f6200025936600462001cae565b62000511565b6040516200026e919062002095565b60405180910390f35b6200028e6200028836600462001cae565b6200052c565b6040516200026e9190620020f1565b6200028e62000541565b6200025f6200058c565b6200022f620002c236600462001cc7565b6200059b565b6200022f620002d936600462001c2c565b620005eb565b6200022f620002f036600462001cc7565b62000690565b6200030d6200030736600462001d8e565b620006d9565b6040516200026e9190620020e6565b6200022f6200032d36600462001e2d565b62000738565b6200028e62000863565b6200028e62000869565b620003516200087c565b6040516200026e9190620020fa565b6200025f6200089f565b6200022f6200037b36600462001ea3565b620008ae565b6200025f62000a14565b6200025f62000a23565b6200022f620003a636600462001c71565b62000a32565b6200030d620003bd36600462001cee565b62000b07565b6200025f620003d436600462001bee565b62000c5e565b6200025f620003eb36600462001d4e565b62000c79565b6200030d6200040236600462001cc7565b62000c9a565b6200028e62000cb4565b6200022f62000cb9565b6200022f6200042d36600462001d8e565b62000d02565b6200028e6200044436600462001cae565b62000dca565b6200022f6200045b36600462001dd2565b62000de3565b6200028e62000ee5565b6200022f6200047c36600462001cc7565b62000f09565b6200030d62000f49565b6200022f6200049d36600462001bee565b62000f59565b620004be60008051602062005c438339815191523362000c9a565b620004e65760405162461bcd60e51b8152600401620004dd9062002340565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b6200050a8585858585620008ae565b5050505050565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000573919062002077565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b600082815260336020526040902060020154620005bc906200040262000fa7565b620005db5760405162461bcd60e51b8152600401620004dd90620021fc565b620005e7828262000fab565b5050565b6067546040516311be333d60e11b81526001600160a01b039091169063237c667a906200061d90859060040162002095565b600060405180830381600087803b1580156200063857600080fd5b505af11580156200064d573d6000803e3d6000fd5b505060408051808201909152600781526613585a5b9b995d60ca1b60208201526069546200068b93509091506001600160a01b031685858562001019565b505050565b6200069a62000fa7565b6001600160a01b0316816001600160a01b031614620006cd5760405162461bcd60e51b8152600401620004dd9062002657565b620005e782826200127f565b6000806001600160a01b0316606a60008585604051602001620006fe92919062002067565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b600085856040516020016200074f92919062002067565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b8483015291519193506200079192910162002077565b60405160208183030381529060405280519060200120811415620007c95760405162461bcd60e51b8152600401620004dd90620022b9565b6000818152606a60205260409020546001600160a01b0316620008005760405162461bcd60e51b8152600401620004dd9062002183565b6200085b86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250868152606a60205260409020546001600160a01b031692508891508790508662001019565b505050505050565b60685481565b60008051602062005c4383398151915281565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b600054610100900460ff1680620008ca5750620008ca620012ed565b80620008d9575060005460ff16155b620008f85760405162461bcd60e51b8152600401620004dd9062002406565b600054610100900460ff1615801562000924576000805460ff1961ff0019909116610100171660011790555b6200092e62001300565b6200093b600033620005db565b6200095660008051602062005c4383398151915233620005db565b620009827ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620005db565b8560405160200162000995919062002077565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b0319928316179092556066805487841690831617905560678054868416908316179055606980549285169290911691909117905580156200085b576000805461ff0019169055505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b62000a5e7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362000c9a565b62000a7d5760405162461bcd60e51b8152600401620004dd90620023d1565b62000a91816001600160a01b0316620013a0565b62000ab05760405162461bcd60e51b8152600401620004dd90620024c2565b6001600160a01b038281166000818152606b602052604080822080546001600160a01b0319169486169485179055517f8d7013baea57225dad80fd4e01f9abc0a832b852212426af1dee770b843472029190a35050565b6065546000906001600160a01b0316331462000b375760405162461bcd60e51b8152600401620004dd906200224b565b606854851415801562000bc957506040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000b77919062002077565b60405160208183030381529060405280519060200120851462000bb7576000858152606a60205260409020546001600160a01b0385811691161462000bc9565b6069546001600160a01b038581169116145b62000be85760405162461bcd60e51b8152600401620004dd9062002583565b600062000bf68484620013a6565b9050600681600c81111562000c0757fe5b148062000c205750600581600c81111562000c1e57fe5b145b1562000c385762000c328484620013f1565b62000c52565b60405162461bcd60e51b8152600401620004dd90620026e9565b50600195945050505050565b606b602052600090815260409020546001600160a01b031681565b600082815260336020526040812062000c93908362001683565b9392505050565b600082815260336020526040812062000c93908362001691565b600081565b62000cd460008051602062005c438339815191523362000c9a565b62000cf35760405162461bcd60e51b8152600401620004dd9062002340565b6069805460ff60a01b19169055565b6066546001600160a01b031633148062000d24575062000d2460003362000c9a565b62000d435760405162461bcd60e51b8152600401620004dd90620025f1565b6000828260405160200162000d5a92919062002067565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031662000daa5760405162461bcd60e51b8152600401620004dd9062002309565b6000908152606a6020526040902080546001600160a01b03191690555050565b60008181526033602052604081206200073290620016a8565b6066546001600160a01b031633148062000e05575062000e0560003362000c9a565b62000e245760405162461bcd60e51b8152600401620004dd90620025f1565b6000838360405160200162000e3b92919062002067565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b03161562000e8c5760405162461bcd60e51b8152600401620004dd90620025ba565b6001600160a01b03821662000eb55760405162461bcd60e51b8152600401620004dd9062002183565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b60008281526033602052604090206002015462000f2a906200040262000fa7565b620006cd5760405162461bcd60e51b8152600401620004dd9062002381565b606954600160a01b900460ff1681565b62000f6660003362000c9a565b62000f855760405162461bcd60e51b8152600401620004dd9062002282565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b600082815260336020526040902062000fc59082620016b5565b15620005e75762000fd562000fa7565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b038216620010425760405162461bcd60e51b8152600401620004dd906200248b565b6001600160a01b038084166000908152606b6020526040902054166200106881620013a0565b620010875760405162461bcd60e51b8152600401620004dd9062002620565b60405163020604bf60e21b815230906001600160a01b0383169063081812fc90620010b7908690600401620020f1565b60206040518083038186803b158015620010d057600080fd5b505afa158015620010e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200110b919062001c0d565b6001600160a01b031614620011345760405162461bcd60e51b8152600401620004dd90620024f9565b6040516323b872dd60e01b81526001600160a01b038216906323b872dd906200116690339030908790600401620020a9565b600060405180830381600087803b1580156200118157600080fd5b505af115801562001196573d6000803e3d6000fd5b5050604051630852cd8d60e31b81526001600160a01b03841692506342966c689150620011c8908590600401620020f1565b600060405180830381600087803b158015620011e357600080fd5b505af1158015620011f8573d6000803e3d6000fd5b5050505060606200120b858585620016cc565b6065546040516365e3781f60e01b81529192506001600160a01b0316906365e3781f9062001242908a908a9086906004016200210f565b600060405180830381600087803b1580156200125d57600080fd5b505af115801562001272573d6000803e3d6000fd5b5050505050505050505050565b600082815260336020526040902062001299908262001743565b15620005e757620012a962000fa7565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000620012fa30620013a0565b15905090565b600054610100900460ff16806200131c57506200131c620012ed565b806200132b575060005460ff16155b6200134a5760405162461bcd60e51b8152600401620004dd9062002406565b600054610100900460ff1615801562001376576000805460ff1961ff0019909116610100171660011790555b620013806200175a565b6200138a6200175a565b80156200139d576000805461ff00191690555b50565b3b151590565b600080620013b78385018562001cae565b905060208106620013e357620013da620013d4848381886200278a565b620013a6565b91505062000732565b620013da8385018562001d70565b6000620013ff8383620013a6565b90506000808080600585600c8111156200141557fe5b141562001472576200142662001a08565b620014328888620017e4565b6040808201516020808401516060909401516001600160a01b038086166000908152606b9093529390912054919850929650919450169150620015969050565b6200147c62001a38565b62001488888862001836565b80516040808201516020808401516060909401516001600160a01b038086166000908152606b90935293909120549199509297509195501692509050816200159457606954600160a01b900460ff16620014f65760405162461bcd60e51b8152600401620004dd9062002454565b60208082015180519101516040516200150f9062001a61565b6200151c92919062002151565b604051809103906000f08015801562001539573d6000803e3d6000fd5b506001600160a01b038581166000818152606b602052604080822080546001600160a01b031916948616948517905551939550919290917faa19c94b56abf04a93a1f32d59067d3918d378afd32b2d1bea847773b7d08f3991a35b505b620015aa816001600160a01b0316620013a0565b620015c95760405162461bcd60e51b8152600401620004dd90620024c2565b6040516340c10f1960e01b81526001600160a01b038216906340c10f1990620015f99087908690600401620020cd565b600060405180830381600087803b1580156200161457600080fd5b505af115801562001629573d6000803e3d6000fd5b50505050806001600160a01b0316836001600160a01b03167fb1196fae12e56db8b0fc57623312e966cbf6b4a45adc9b3002df48577de9f3b184604051620016729190620020f1565b60405180910390a350505050505050565b600062000c93838362001888565b600062000c93836001600160a01b038416620018d1565b60006200073282620018e9565b600062000c93836001600160a01b038416620018ed565b6060620016d862001a08565b6040805160a0810190915280608081018060058152508152602001866001600160a01b03168152602001856001600160a01b03168152602001848152509050806040516020016200172a919062002719565b6040516020818303038152906040529150509392505050565b600062000c93836001600160a01b0384166200193c565b600054610100900460ff168062001776575062001776620012ed565b8062001785575060005460ff16155b620017a45760405162461bcd60e51b8152600401620004dd9062002406565b600054610100900460ff161580156200138a576000805460ff1961ff00199091166101001716600117905580156200139d576000805461ff001916905550565b620017ee62001a08565b6005620017fc8484620013a6565b600c8111156200180857fe5b14620018285760405162461bcd60e51b8152600401620004dd90620026a6565b62000c93828401846200201b565b6200184062001a38565b60066200184e8484620013a6565b600c8111156200185a57fe5b146200187a5760405162461bcd60e51b8152600401620004dd9062002530565b62000c938284018462001f37565b81546000908210620018ae5760405162461bcd60e51b8152600401620004dd90620021ba565b826000018281548110620018be57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000620018fb8383620018d1565b620019335750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000732565b50600062000732565b60008181526001830160205260408120548015620019fd57835460001980830191908101906000908790839081106200197157fe5b90600052602060002001549050808760000184815481106200198f57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080620019c057fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505062000732565b600091505062000732565b604051806080016040528062001a1d62001a6f565b81526000602082018190526040820181905260609091015290565b604051806040016040528062001a4d62001a08565b815260200162001a5c62001a83565b905290565b61344580620027fe83390190565b604080516020810190915280600062001a5c565b604051806040016040528060608152602001606081525090565b60008083601f84011262001aaf578182fd5b50813567ffffffffffffffff81111562001ac7578182fd5b60208301915083602082850101111562001ae057600080fd5b9250929050565b8035600d81106200073257600080fd5b600082601f83011262001b08578081fd5b813567ffffffffffffffff81111562001b1f578182fd5b62001b34601f8201601f191660200162002762565b915080825283602082850101111562001b4c57600080fd5b8060208401602084013760009082016020015292915050565b6000818303608081121562001b78578182fd5b62001b84608062002762565b9150602081121562001b9557600080fd5b5062001ba2602062002762565b62001bae848462001ae7565b81528152602082013562001bc281620027e7565b6020820152604082013562001bd781620027e7565b806040830152506060820135606082015292915050565b60006020828403121562001c00578081fd5b813562000c9381620027e7565b60006020828403121562001c1f578081fd5b815162000c9381620027e7565b60008060006060848603121562001c41578182fd5b833562001c4e81620027e7565b9250602084013562001c6081620027e7565b929592945050506040919091013590565b6000806040838503121562001c84578182fd5b823562001c9181620027e7565b9150602083013562001ca381620027e7565b809150509250929050565b60006020828403121562001cc0578081fd5b5035919050565b6000806040838503121562001cda578182fd5b82359150602083013562001ca381620027e7565b6000806000806060858703121562001d04578081fd5b84359350602085013562001d1881620027e7565b9250604085013567ffffffffffffffff81111562001d34578182fd5b62001d428782880162001a9d565b95989497509550505050565b6000806040838503121562001d61578182fd5b50508035926020909101359150565b60006020828403121562001d82578081fd5b62000c93838362001ae7565b6000806020838503121562001da1578182fd5b823567ffffffffffffffff81111562001db8578283fd5b62001dc68582860162001a9d565b90969095509350505050565b60008060006040848603121562001de7578081fd5b833567ffffffffffffffff81111562001dfe578182fd5b62001e0c8682870162001a9d565b909450925050602084013562001e2281620027e7565b809150509250925092565b60008060008060006080868803121562001e45578283fd5b853567ffffffffffffffff81111562001e5c578384fd5b62001e6a8882890162001a9d565b909650945050602086013562001e8081620027e7565b9250604086013562001e9281620027e7565b949793965091946060013592915050565b600080600080600060a0868803121562001ebb578283fd5b853567ffffffffffffffff81111562001ed2578384fd5b62001ee08882890162001af7565b955050602086013562001ef381620027e7565b9350604086013562001f0581620027e7565b9250606086013562001f1781620027e7565b9150608086013562001f2981620027e7565b809150509295509295909350565b60006020828403121562001f49578081fd5b813567ffffffffffffffff8082111562001f61578283fd5b9083019060a0828603121562001f75578283fd5b62001f81604062002762565b62001f8d868462001b65565b815260808301358281111562001fa1578485fd5b92909201916040838703121562001fb6578384fd5b62001fc2604062002762565b83358381111562001fd1578586fd5b62001fdf8882870162001af7565b82525060208401358381111562001ff4578586fd5b620020028882870162001af7565b6020830152508060208301525080935050505092915050565b6000608082840312156200202d578081fd5b62000c93838362001b65565b6000815180845262002053816020860160208601620027b4565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b600082516200208b818460208701620027b4565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b60006020825262000c93602083018462002039565b60006060825262002124606083018662002039565b6001600160a01b0385166020840152828103604084015262002147818562002039565b9695505050505050565b60006040825262002166604083018562002039565b82810360208401526200217a818562002039565b95945050505050565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601c908201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604082015260600190565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b60208082526018908201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604082015260600190565b60208082526033908201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604082015272666572207769746820746f6b656e20696e666f60681b606082015260800190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b60208082526018908201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60208082526023908201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736040820152623332b960e91b606082015260800190565b60208082526016908201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604082015260600190565b8151516080820190600d81106200272c57fe5b80835250602083015160018060a01b03808216602085015280604086015116604085015250506060830151606083015292915050565b60405181810167ffffffffffffffff811182821017156200278257600080fd5b604052919050565b600080858511156200279a578182fd5b83861115620027a7578182fd5b5050820193919092039150565b60005b83811015620027d1578181015183820152602001620027b7565b83811115620027e1576000848401525b50505050565b6001600160a01b03811681146200139d57600080fdfe60806040523480156200001157600080fd5b506040516200344538038062003445833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604052505050620001b46200022760201b620012c81760201c565b620001cb8282620002e560201b620013791760201c565b620001e0620003b160201b620014361760201c565b620001fb600080516020620034258339815191528062000459565b6200021f6000805160206200342583398151915262000219620004ab565b620004af565b50506200094a565b600054610100900460ff168062000243575062000243620004bf565b8062000252575060005460ff16155b6200028f5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620002bb576000805460ff1961ff0019909116610100171660011790555b620002c5620004dd565b620002cf620004dd565b8015620002e2576000805461ff00191690555b50565b600054610100900460ff168062000301575062000301620004bf565b8062000310575060005460ff16155b6200034d5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000379576000805460ff1961ff0019909116610100171660011790555b62000383620004dd565b6200038d62000585565b6200039983836200062b565b8015620003ac576000805461ff00191690555b505050565b600054610100900460ff1680620003cd5750620003cd620004bf565b80620003dc575060005460ff16155b620004195760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000445576000805460ff1961ff0019909116610100171660011790555b6200044f620004dd565b620002c562000585565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620004bb828262000721565b5050565b6000620004d7306200079c60201b620014d31760201c565b15905090565b600054610100900460ff1680620004f95750620004f9620004bf565b8062000508575060005460ff16155b620005455760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620002cf576000805460ff1961ff0019909116610100171660011790558015620002e2576000805461ff001916905550565b600054610100900460ff1680620005a15750620005a1620004bf565b80620005b0575060005460ff16155b620005ed5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000619576000805460ff1961ff0019909116610100171660011790555b620002cf6301ffc9a760e01b620007a2565b600054610100900460ff168062000647575062000647620004bf565b8062000656575060005460ff16155b620006935760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620006bf576000805460ff1961ff0019909116610100171660011790555b8251620006d490609c906020860190620008ae565b508151620006ea90609d906020850190620008ae565b50620006fd6380ac58cd60e01b620007a2565b6200070f635b5e139f60e01b620007a2565b6200039963780e9d6360e01b620007a2565b600082815260336020908152604090912062000748918390620014d962000827821b17901c565b15620004bb5762000758620004ab565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b6001600160e01b0319808216141562000802576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b60006200083e836001600160a01b03841662000847565b90505b92915050565b600062000855838362000896565b6200088d5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000841565b50600062000841565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620008f157805160ff191683800117855562000921565b8280016001018555821562000921579182015b828111156200092157825182559160200191906001019062000904565b506200092f92915062000933565b5090565b5b808211156200092f576000815560010162000934565b612a9d806200095a6000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80634f6ccce711610104578063a217fddf116100a2578063ca15c87311610071578063ca15c873146106b2578063d5391393146106cf578063d547741f146106d7578063e985e9c514610703576101cf565b8063a217fddf14610599578063a22cb465146105a1578063b88d4fde146105cf578063c87b56dd14610695576101cf565b806370a08231116100de57806370a082311461051c5780639010d07c1461054257806391d148541461056557806395d89b4114610591576101cf565b80634f6ccce7146104da5780636352211e146104f75780636c0360eb14610514576101cf565b8063248a9ca31161017157806336568abe1161014b57806336568abe1461042f57806340c10f191461045b57806342842e0e1461048757806342966c68146104bd576101cf565b8063248a9ca3146103ba5780632f2ff15d146103d75780632f745c5914610403576101cf565b8063095ea7b3116101ad578063095ea7b3146102c5578063162094c4146102f357806318160ddd1461036a57806323b872dd14610384576101cf565b806301ffc9a7146101d457806306fdde031461020f578063081812fc1461028c575b600080fd5b6101fb600480360360208110156101ea57600080fd5b50356001600160e01b031916610731565b604080519115158252519081900360200190f35b610217610754565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610251578181015183820152602001610239565b50505050905090810190601f16801561027e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102a9600480360360208110156102a257600080fd5b50356107ea565b604080516001600160a01b039092168252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b506001600160a01b03813516906020013561084c565b005b6101fb6004803603604081101561030957600080fd5b8135919081019060408101602082013564010000000081111561032b57600080fd5b82018360208201111561033d57600080fd5b8035906020019184600183028401116401000000008311171561035f57600080fd5b509092509050610927565b610372610a21565b60408051918252519081900360200190f35b6102f16004803603606081101561039a57600080fd5b506001600160a01b03813581169160208101359091169060400135610a32565b610372600480360360208110156103d057600080fd5b5035610a89565b6102f1600480360360408110156103ed57600080fd5b50803590602001356001600160a01b0316610a9e565b6103726004803603604081101561041957600080fd5b506001600160a01b038135169060200135610b0a565b6102f16004803603604081101561044557600080fd5b50803590602001356001600160a01b0316610b35565b6102f16004803603604081101561047157600080fd5b506001600160a01b038135169060200135610b96565b6102f16004803603606081101561049d57600080fd5b506001600160a01b03813581169160208101359091169060400135610c16565b6102f1600480360360208110156104d357600080fd5b5035610c31565b610372600480360360208110156104f057600080fd5b5035610c83565b6102a96004803603602081101561050d57600080fd5b5035610c99565b610217610cc1565b6103726004803603602081101561053257600080fd5b50356001600160a01b0316610d22565b6102a96004803603604081101561055857600080fd5b5080359060200135610d8a565b6101fb6004803603604081101561057b57600080fd5b50803590602001356001600160a01b0316610da2565b610217610dba565b610372610e1b565b6102f1600480360360408110156105b757600080fd5b506001600160a01b0381351690602001351515610e20565b6102f1600480360360808110156105e557600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561062057600080fd5b82018360208201111561063257600080fd5b8035906020019184600183028401116401000000008311171561065457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f25945050505050565b610217600480360360208110156106ab57600080fd5b5035610f83565b610372600480360360208110156106c857600080fd5b5035611206565b61037261121d565b6102f1600480360360408110156106ed57600080fd5b50803590602001356001600160a01b0316611241565b6101fb6004803603604081101561071957600080fd5b506001600160a01b038135811691602001351661129a565b6001600160e01b0319811660009081526065602052604090205460ff165b919050565b609c8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b820191906000526020600020905b8154815290600101906020018083116107c357829003601f168201915b5050505050905090565b60006107f5826114ee565b6108305760405162461bcd60e51b815260040180806020018281038252602c815260200180612907602c913960400191505060405180910390fd5b506000908152609a60205260409020546001600160a01b031690565b600061085782610c99565b9050806001600160a01b0316836001600160a01b031614156108aa5760405162461bcd60e51b81526004018080602001828103825260218152602001806129b76021913960400191505060405180910390fd5b806001600160a01b03166108bc6114fb565b6001600160a01b031614806108dd57506108dd816108d86114fb565b61129a565b6109185760405162461bcd60e51b815260040180806020018281038252603881526020018061282c6038913960400191505060405180910390fd5b61092283836114ff565b505050565b6000610932846114ee565b61097b576040805162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b604482015290519081900360640190fd5b610985338561156d565b6109d6576040805162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e2055524900000000604482015290519081900360640190fd5b610a168484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161192505050565b5060015b9392505050565b6000610a2d6098611674565b905090565b610a43610a3d6114fb565b8261156d565b610a7e5760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b61092283838361167f565b60009081526033602052604090206002015490565b600082815260336020526040902060020154610ac190610abc6114fb565b610da2565b610afc5760405162461bcd60e51b815260040180806020018281038252602f81526020018061274b602f913960400191505060405180910390fd5b610b0682826117cb565b5050565b6001600160a01b0382166000908152609760205260408120610b2c9083611834565b90505b92915050565b610b3d6114fb565b6001600160a01b0316816001600160a01b031614610b8c5760405162461bcd60e51b815260040180806020018281038252602f815260200180612a39602f913960400191505060405180910390fd5b610b068282611840565b610bc27f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610abc6114fb565b610c0c576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610b0682826118a9565b61092283838360405180602001604052806000815250610f25565b610c3c610a3d6114fb565b610c775760405162461bcd60e51b8152600401808060200182810382526030815260200180612a096030913960400191505060405180910390fd5b610c80816119d7565b50565b600080610c91609884611aa4565b509392505050565b6000610b2f8260405180606001604052806029815260200161288e6029913960989190611ac0565b609f8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b60006001600160a01b038216610d695760405162461bcd60e51b815260040180806020018281038252602a815260200180612864602a913960400191505060405180910390fd5b6001600160a01b0382166000908152609760205260409020610b2f90611674565b6000828152603360205260408120610b2c9083611834565b6000828152603360205260408120610b2c9083611acd565b609d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b600081565b610e286114fb565b6001600160a01b0316826001600160a01b03161415610e8e576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80609b6000610e9b6114fb565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610edf6114fb565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610f36610f306114fb565b8361156d565b610f715760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b610f7d84848484611ae2565b50505050565b6060610f8e826114ee565b610fc95760405162461bcd60e51b815260040180806020018281038252602f815260200180612988602f913960400191505060405180910390fd5b6000828152609e602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561105e5780601f106110335761010080835404028352916020019161105e565b820191906000526020600020905b81548152906001019060200180831161104157829003601f168201915b50505050509050606061106f610cc1565b90508051600014156110835750905061074f565b8151156111445780826040516020018083805190602001908083835b602083106110be5780518252601f19909201916020918201910161109f565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111065780518252601f1990920191602091820191016110e7565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061074f565b8061114e85611b34565b6040516020018083805190602001908083835b602083106111805780518252601f199092019160209182019101611161565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111c85780518252601f1990920191602091820191016111a9565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b6000818152603360205260408120610b2f90611674565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b60008281526033602052604090206002015461125f90610abc6114fb565b610b8c5760405162461bcd60e51b81526004018080602001828103825260308152602001806127fc6030913960400191505060405180910390fd5b6001600160a01b039182166000908152609b6020908152604080832093909416825291909152205460ff1690565b600054610100900460ff16806112e157506112e1611c0f565b806112ef575060005460ff16155b61132a5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611355576000805460ff1961ff0019909116610100171660011790555b61135d611c20565b611365611c20565b8015610c80576000805461ff001916905550565b600054610100900460ff16806113925750611392611c0f565b806113a0575060005460ff16155b6113db5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611406576000805460ff1961ff0019909116610100171660011790555b61140e611c20565b611416611cc0565b6114208383611d5d565b8015610922576000805461ff0019169055505050565b600054610100900460ff168061144f575061144f611c0f565b8061145d575060005460ff16155b6114985760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff161580156114c3576000805460ff1961ff0019909116610100171660011790555b6114cb611c20565b61135d611cc0565b3b151590565b6000610b2c836001600160a01b038416611e42565b6000610b2f609883611e8c565b3390565b6000818152609a6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061153482610c99565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611578826114ee565b6115b35760405162461bcd60e51b815260040180806020018281038252602c8152602001806127d0602c913960400191505060405180910390fd5b60006115be83610c99565b9050806001600160a01b0316846001600160a01b031614806115f95750836001600160a01b03166115ee846107ea565b6001600160a01b0316145b806116095750611609818561129a565b949350505050565b61161a826114ee565b6116555760405162461bcd60e51b815260040180806020018281038252602c815260200180612933602c913960400191505060405180910390fd5b6000828152609e60209081526040909120825161092292840190612655565b6000610b2f82611e98565b826001600160a01b031661169282610c99565b6001600160a01b0316146116d75760405162461bcd60e51b815260040180806020018281038252602981526020018061295f6029913960400191505060405180910390fd5b6001600160a01b03821661171c5760405162461bcd60e51b81526004018080602001828103825260248152602001806127ac6024913960400191505060405180910390fd5b611727838383610922565b6117326000826114ff565b6001600160a01b03831660009081526097602052604090206117549082611e9c565b506001600160a01b03821660009081526097602052604090206117779082611ea8565b5061178460988284611eb4565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526033602052604090206117e390826114d9565b15610b06576117f06114fb565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610b2c8383611eca565b60008281526033602052604090206118589082611f2e565b15610b06576118656114fb565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038216611904576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61190d816114ee565b1561195f576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b61196b60008383610922565b6001600160a01b038216600090815260976020526040902061198d9082611ea8565b5061199a60988284611eb4565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006119e282610c99565b90506119f081600084610922565b6119fb6000836114ff565b6000828152609e60205260409020546002600019610100600184161502019091160415611a39576000828152609e60205260408120611a39916126d3565b6001600160a01b0381166000908152609760205260409020611a5b9083611e9c565b50611a67609883611f43565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000808080611ab38686611f4f565b9097909650945050505050565b6000611609848484611fca565b6000610b2c836001600160a01b038416612094565b611aed84848461167f565b611af9848484846120ac565b610f7d5760405162461bcd60e51b815260040180806020018281038252603281526020018061277a6032913960400191505060405180910390fd5b606081611b5957506040805180820190915260018152600360fc1b602082015261074f565b8160005b8115611b7157600101600a82049150611b5d565b60608167ffffffffffffffff81118015611b8a57600080fd5b506040519080825280601f01601f191660200182016040528015611bb5576020820181803683370190505b50859350905060001982015b8315611c0657600a840660300160f81b82828060019003935081518110611be457fe5b60200101906001600160f81b031916908160001a905350600a84049350611bc1565b50949350505050565b6000611c1a306114d3565b15905090565b600054610100900460ff1680611c395750611c39611c0f565b80611c47575060005460ff16155b611c825760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611365576000805460ff1961ff0019909116610100171660011790558015610c80576000805461ff001916905550565b600054610100900460ff1680611cd95750611cd9611c0f565b80611ce7575060005460ff16155b611d225760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611d4d576000805460ff1961ff0019909116610100171660011790555b6113656301ffc9a760e01b612214565b600054610100900460ff1680611d765750611d76611c0f565b80611d84575060005460ff16155b611dbf5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611dea576000805460ff1961ff0019909116610100171660011790555b8251611dfd90609c906020860190612655565b508151611e1190609d906020850190612655565b50611e226380ac58cd60e01b612214565b611e32635b5e139f60e01b612214565b61142063780e9d6360e01b612214565b6000611e4e8383612094565b611e8457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b2f565b506000610b2f565b6000610b2c8383612094565b5490565b6000610b2c8383612298565b6000610b2c8383611e42565b600061160984846001600160a01b03851661235e565b81546000908210611f0c5760405162461bcd60e51b81526004018080602001828103825260228152602001806127296022913960400191505060405180910390fd5b826000018281548110611f1b57fe5b9060005260206000200154905092915050565b6000610b2c836001600160a01b038416612298565b6000610b2c83836123f5565b815460009081908310611f935760405162461bcd60e51b81526004018080602001828103825260228152602001806128e56022913960400191505060405180910390fd5b6000846000018481548110611fa457fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816120655760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561202a578181015183820152602001612012565b50505050905090810190601f1680156120575780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061207857fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b60006120c0846001600160a01b03166114d3565b6120cc57506001611609565b60606121da630a85bd0160e11b6120e16114fb565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612148578181015183820152602001612130565b50505050905090810190601f1680156121755780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161277a603291396001600160a01b03881691906124c9565b905060008180602001905160208110156121f357600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160e01b03198082161415612273576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b6000818152600183016020526040812054801561235457835460001980830191908101906000908790839081106122cb57fe5b90600052602060002001549050808760000184815481106122e857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061231857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b2f565b6000915050610b2f565b6000828152600184016020526040812054806123c3575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055610a1a565b828560000160018303815481106123d657fe5b9060005260206000209060020201600101819055506000915050610a1a565b60008181526001830160205260408120548015612354578354600019808301919081019060009087908390811061242857fe5b906000526020600020906002020190508087600001848154811061244857fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061248757fe5b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610b2f9350505050565b60606116098484600085856124dd856114d3565b61252e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061256d5780518252601f19909201916020918201910161254e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146125cf576040519150601f19603f3d011682016040523d82523d6000602084013e6125d4565b606091505b50915091506125e48282866125ef565b979650505050505050565b606083156125fe575081610a1a565b82511561260e5782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561202a578181015183820152602001612012565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061269657805160ff19168380011785556126c3565b828001600101855582156126c3579182015b828111156126c35782518255916020019190600101906126a8565b506126cf929150612713565b5090565b50805460018160011615610100020316600290046000825580601f106126f95750610c80565b601f016020900490600052602060002090810190610c8091905b5b808211156126cf576000815560010161271456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212206cfed4af0d06c86fc24af2eff048829ddbcce69495200e80936dbbfb68bcbc3964736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba26469706673582212203dcb732cfab6450457532ede4a1839d6b27deedb542d9b799556400ffd8941ff64736f6c634300060c0033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002205760003560e01c80636d6112861162000129578063b9581c5011620000b1578063cc5b715b116200007b578063cc5b715b1462000461578063d547741f146200046b578063dec2deb61462000482578063edcc12b5146200048c5762000220565b8063b9581c501462000412578063c0e312dc146200041c578063ca15c8731462000433578063cb703bff146200044a5762000220565b80638a8fe42111620000f35780638a8fe42114620003c35780639010d07c14620003da57806391d1485414620003f1578063a217fddf14620004085762000220565b80636d61128614620003815780636d6c68e6146200038b5780637b69620f1462000395578063884cee5a14620003ac5762000220565b806336568abe11620001ad5780633fa194ce11620001775780633fa194ce146200033d57806350f4428014620003475780635573b8b614620003605780636ce681d2146200036a5762000220565b806336568abe14620002df57806339927cf914620002f65780633b4612c1146200031c5780633b690b6b14620003335762000220565b806328c5e18211620001ef57806328c5e182146200029d5780632dc151de14620002a75780632f2ff15d14620002b157806330d86b2a14620002c85762000220565b8063029996b814620002255780630b885ac314620002315780630f1a8f741462000248578063248a9ca31462000277575b600080fd5b6200022f620004a3565b005b6200022f6200024236600462001ea3565b620004fb565b6200025f6200025936600462001cae565b62000511565b6040516200026e919062002095565b60405180910390f35b6200028e6200028836600462001cae565b6200052c565b6040516200026e9190620020f1565b6200028e62000541565b6200025f6200058c565b6200022f620002c236600462001cc7565b6200059b565b6200022f620002d936600462001c2c565b620005eb565b6200022f620002f036600462001cc7565b62000690565b6200030d6200030736600462001d8e565b620006d9565b6040516200026e9190620020e6565b6200022f6200032d36600462001e2d565b62000738565b6200028e62000863565b6200028e62000869565b620003516200087c565b6040516200026e9190620020fa565b6200025f6200089f565b6200022f6200037b36600462001ea3565b620008ae565b6200025f62000a14565b6200025f62000a23565b6200022f620003a636600462001c71565b62000a32565b6200030d620003bd36600462001cee565b62000b07565b6200025f620003d436600462001bee565b62000c5e565b6200025f620003eb36600462001d4e565b62000c79565b6200030d6200040236600462001cc7565b62000c9a565b6200028e62000cb4565b6200022f62000cb9565b6200022f6200042d36600462001d8e565b62000d02565b6200028e6200044436600462001cae565b62000dca565b6200022f6200045b36600462001dd2565b62000de3565b6200028e62000ee5565b6200022f6200047c36600462001cc7565b62000f09565b6200030d62000f49565b6200022f6200049d36600462001bee565b62000f59565b620004be60008051602062005c438339815191523362000c9a565b620004e65760405162461bcd60e51b8152600401620004dd9062002340565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b6200050a8585858585620008ae565b5050505050565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000573919062002077565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b600082815260336020526040902060020154620005bc906200040262000fa7565b620005db5760405162461bcd60e51b8152600401620004dd90620021fc565b620005e7828262000fab565b5050565b6067546040516311be333d60e11b81526001600160a01b039091169063237c667a906200061d90859060040162002095565b600060405180830381600087803b1580156200063857600080fd5b505af11580156200064d573d6000803e3d6000fd5b505060408051808201909152600781526613585a5b9b995d60ca1b60208201526069546200068b93509091506001600160a01b031685858562001019565b505050565b6200069a62000fa7565b6001600160a01b0316816001600160a01b031614620006cd5760405162461bcd60e51b8152600401620004dd9062002657565b620005e782826200127f565b6000806001600160a01b0316606a60008585604051602001620006fe92919062002067565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b600085856040516020016200074f92919062002067565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b8483015291519193506200079192910162002077565b60405160208183030381529060405280519060200120811415620007c95760405162461bcd60e51b8152600401620004dd90620022b9565b6000818152606a60205260409020546001600160a01b0316620008005760405162461bcd60e51b8152600401620004dd9062002183565b6200085b86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250868152606a60205260409020546001600160a01b031692508891508790508662001019565b505050505050565b60685481565b60008051602062005c4383398151915281565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b600054610100900460ff1680620008ca5750620008ca620012ed565b80620008d9575060005460ff16155b620008f85760405162461bcd60e51b8152600401620004dd9062002406565b600054610100900460ff1615801562000924576000805460ff1961ff0019909116610100171660011790555b6200092e62001300565b6200093b600033620005db565b6200095660008051602062005c4383398151915233620005db565b620009827ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620005db565b8560405160200162000995919062002077565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b0319928316179092556066805487841690831617905560678054868416908316179055606980549285169290911691909117905580156200085b576000805461ff0019169055505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b62000a5e7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362000c9a565b62000a7d5760405162461bcd60e51b8152600401620004dd90620023d1565b62000a91816001600160a01b0316620013a0565b62000ab05760405162461bcd60e51b8152600401620004dd90620024c2565b6001600160a01b038281166000818152606b602052604080822080546001600160a01b0319169486169485179055517f8d7013baea57225dad80fd4e01f9abc0a832b852212426af1dee770b843472029190a35050565b6065546000906001600160a01b0316331462000b375760405162461bcd60e51b8152600401620004dd906200224b565b606854851415801562000bc957506040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000b77919062002077565b60405160208183030381529060405280519060200120851462000bb7576000858152606a60205260409020546001600160a01b0385811691161462000bc9565b6069546001600160a01b038581169116145b62000be85760405162461bcd60e51b8152600401620004dd9062002583565b600062000bf68484620013a6565b9050600681600c81111562000c0757fe5b148062000c205750600581600c81111562000c1e57fe5b145b1562000c385762000c328484620013f1565b62000c52565b60405162461bcd60e51b8152600401620004dd90620026e9565b50600195945050505050565b606b602052600090815260409020546001600160a01b031681565b600082815260336020526040812062000c93908362001683565b9392505050565b600082815260336020526040812062000c93908362001691565b600081565b62000cd460008051602062005c438339815191523362000c9a565b62000cf35760405162461bcd60e51b8152600401620004dd9062002340565b6069805460ff60a01b19169055565b6066546001600160a01b031633148062000d24575062000d2460003362000c9a565b62000d435760405162461bcd60e51b8152600401620004dd90620025f1565b6000828260405160200162000d5a92919062002067565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031662000daa5760405162461bcd60e51b8152600401620004dd9062002309565b6000908152606a6020526040902080546001600160a01b03191690555050565b60008181526033602052604081206200073290620016a8565b6066546001600160a01b031633148062000e05575062000e0560003362000c9a565b62000e245760405162461bcd60e51b8152600401620004dd90620025f1565b6000838360405160200162000e3b92919062002067565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b03161562000e8c5760405162461bcd60e51b8152600401620004dd90620025ba565b6001600160a01b03821662000eb55760405162461bcd60e51b8152600401620004dd9062002183565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b60008281526033602052604090206002015462000f2a906200040262000fa7565b620006cd5760405162461bcd60e51b8152600401620004dd9062002381565b606954600160a01b900460ff1681565b62000f6660003362000c9a565b62000f855760405162461bcd60e51b8152600401620004dd9062002282565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b600082815260336020526040902062000fc59082620016b5565b15620005e75762000fd562000fa7565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b038216620010425760405162461bcd60e51b8152600401620004dd906200248b565b6001600160a01b038084166000908152606b6020526040902054166200106881620013a0565b620010875760405162461bcd60e51b8152600401620004dd9062002620565b60405163020604bf60e21b815230906001600160a01b0383169063081812fc90620010b7908690600401620020f1565b60206040518083038186803b158015620010d057600080fd5b505afa158015620010e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200110b919062001c0d565b6001600160a01b031614620011345760405162461bcd60e51b8152600401620004dd90620024f9565b6040516323b872dd60e01b81526001600160a01b038216906323b872dd906200116690339030908790600401620020a9565b600060405180830381600087803b1580156200118157600080fd5b505af115801562001196573d6000803e3d6000fd5b5050604051630852cd8d60e31b81526001600160a01b03841692506342966c689150620011c8908590600401620020f1565b600060405180830381600087803b158015620011e357600080fd5b505af1158015620011f8573d6000803e3d6000fd5b5050505060606200120b858585620016cc565b6065546040516365e3781f60e01b81529192506001600160a01b0316906365e3781f9062001242908a908a9086906004016200210f565b600060405180830381600087803b1580156200125d57600080fd5b505af115801562001272573d6000803e3d6000fd5b5050505050505050505050565b600082815260336020526040902062001299908262001743565b15620005e757620012a962000fa7565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000620012fa30620013a0565b15905090565b600054610100900460ff16806200131c57506200131c620012ed565b806200132b575060005460ff16155b6200134a5760405162461bcd60e51b8152600401620004dd9062002406565b600054610100900460ff1615801562001376576000805460ff1961ff0019909116610100171660011790555b620013806200175a565b6200138a6200175a565b80156200139d576000805461ff00191690555b50565b3b151590565b600080620013b78385018562001cae565b905060208106620013e357620013da620013d4848381886200278a565b620013a6565b91505062000732565b620013da8385018562001d70565b6000620013ff8383620013a6565b90506000808080600585600c8111156200141557fe5b141562001472576200142662001a08565b620014328888620017e4565b6040808201516020808401516060909401516001600160a01b038086166000908152606b9093529390912054919850929650919450169150620015969050565b6200147c62001a38565b62001488888862001836565b80516040808201516020808401516060909401516001600160a01b038086166000908152606b90935293909120549199509297509195501692509050816200159457606954600160a01b900460ff16620014f65760405162461bcd60e51b8152600401620004dd9062002454565b60208082015180519101516040516200150f9062001a61565b6200151c92919062002151565b604051809103906000f08015801562001539573d6000803e3d6000fd5b506001600160a01b038581166000818152606b602052604080822080546001600160a01b031916948616948517905551939550919290917faa19c94b56abf04a93a1f32d59067d3918d378afd32b2d1bea847773b7d08f3991a35b505b620015aa816001600160a01b0316620013a0565b620015c95760405162461bcd60e51b8152600401620004dd90620024c2565b6040516340c10f1960e01b81526001600160a01b038216906340c10f1990620015f99087908690600401620020cd565b600060405180830381600087803b1580156200161457600080fd5b505af115801562001629573d6000803e3d6000fd5b50505050806001600160a01b0316836001600160a01b03167fb1196fae12e56db8b0fc57623312e966cbf6b4a45adc9b3002df48577de9f3b184604051620016729190620020f1565b60405180910390a350505050505050565b600062000c93838362001888565b600062000c93836001600160a01b038416620018d1565b60006200073282620018e9565b600062000c93836001600160a01b038416620018ed565b6060620016d862001a08565b6040805160a0810190915280608081018060058152508152602001866001600160a01b03168152602001856001600160a01b03168152602001848152509050806040516020016200172a919062002719565b6040516020818303038152906040529150509392505050565b600062000c93836001600160a01b0384166200193c565b600054610100900460ff168062001776575062001776620012ed565b8062001785575060005460ff16155b620017a45760405162461bcd60e51b8152600401620004dd9062002406565b600054610100900460ff161580156200138a576000805460ff1961ff00199091166101001716600117905580156200139d576000805461ff001916905550565b620017ee62001a08565b6005620017fc8484620013a6565b600c8111156200180857fe5b14620018285760405162461bcd60e51b8152600401620004dd90620026a6565b62000c93828401846200201b565b6200184062001a38565b60066200184e8484620013a6565b600c8111156200185a57fe5b146200187a5760405162461bcd60e51b8152600401620004dd9062002530565b62000c938284018462001f37565b81546000908210620018ae5760405162461bcd60e51b8152600401620004dd90620021ba565b826000018281548110620018be57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000620018fb8383620018d1565b620019335750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000732565b50600062000732565b60008181526001830160205260408120548015620019fd57835460001980830191908101906000908790839081106200197157fe5b90600052602060002001549050808760000184815481106200198f57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080620019c057fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505062000732565b600091505062000732565b604051806080016040528062001a1d62001a6f565b81526000602082018190526040820181905260609091015290565b604051806040016040528062001a4d62001a08565b815260200162001a5c62001a83565b905290565b61344580620027fe83390190565b604080516020810190915280600062001a5c565b604051806040016040528060608152602001606081525090565b60008083601f84011262001aaf578182fd5b50813567ffffffffffffffff81111562001ac7578182fd5b60208301915083602082850101111562001ae057600080fd5b9250929050565b8035600d81106200073257600080fd5b600082601f83011262001b08578081fd5b813567ffffffffffffffff81111562001b1f578182fd5b62001b34601f8201601f191660200162002762565b915080825283602082850101111562001b4c57600080fd5b8060208401602084013760009082016020015292915050565b6000818303608081121562001b78578182fd5b62001b84608062002762565b9150602081121562001b9557600080fd5b5062001ba2602062002762565b62001bae848462001ae7565b81528152602082013562001bc281620027e7565b6020820152604082013562001bd781620027e7565b806040830152506060820135606082015292915050565b60006020828403121562001c00578081fd5b813562000c9381620027e7565b60006020828403121562001c1f578081fd5b815162000c9381620027e7565b60008060006060848603121562001c41578182fd5b833562001c4e81620027e7565b9250602084013562001c6081620027e7565b929592945050506040919091013590565b6000806040838503121562001c84578182fd5b823562001c9181620027e7565b9150602083013562001ca381620027e7565b809150509250929050565b60006020828403121562001cc0578081fd5b5035919050565b6000806040838503121562001cda578182fd5b82359150602083013562001ca381620027e7565b6000806000806060858703121562001d04578081fd5b84359350602085013562001d1881620027e7565b9250604085013567ffffffffffffffff81111562001d34578182fd5b62001d428782880162001a9d565b95989497509550505050565b6000806040838503121562001d61578182fd5b50508035926020909101359150565b60006020828403121562001d82578081fd5b62000c93838362001ae7565b6000806020838503121562001da1578182fd5b823567ffffffffffffffff81111562001db8578283fd5b62001dc68582860162001a9d565b90969095509350505050565b60008060006040848603121562001de7578081fd5b833567ffffffffffffffff81111562001dfe578182fd5b62001e0c8682870162001a9d565b909450925050602084013562001e2281620027e7565b809150509250925092565b60008060008060006080868803121562001e45578283fd5b853567ffffffffffffffff81111562001e5c578384fd5b62001e6a8882890162001a9d565b909650945050602086013562001e8081620027e7565b9250604086013562001e9281620027e7565b949793965091946060013592915050565b600080600080600060a0868803121562001ebb578283fd5b853567ffffffffffffffff81111562001ed2578384fd5b62001ee08882890162001af7565b955050602086013562001ef381620027e7565b9350604086013562001f0581620027e7565b9250606086013562001f1781620027e7565b9150608086013562001f2981620027e7565b809150509295509295909350565b60006020828403121562001f49578081fd5b813567ffffffffffffffff8082111562001f61578283fd5b9083019060a0828603121562001f75578283fd5b62001f81604062002762565b62001f8d868462001b65565b815260808301358281111562001fa1578485fd5b92909201916040838703121562001fb6578384fd5b62001fc2604062002762565b83358381111562001fd1578586fd5b62001fdf8882870162001af7565b82525060208401358381111562001ff4578586fd5b620020028882870162001af7565b6020830152508060208301525080935050505092915050565b6000608082840312156200202d578081fd5b62000c93838362001b65565b6000815180845262002053816020860160208601620027b4565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b600082516200208b818460208701620027b4565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b60006020825262000c93602083018462002039565b60006060825262002124606083018662002039565b6001600160a01b0385166020840152828103604084015262002147818562002039565b9695505050505050565b60006040825262002166604083018562002039565b82810360208401526200217a818562002039565b95945050505050565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601c908201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604082015260600190565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b6020808252601f908201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604082015260600190565b60208082526018908201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604082015260600190565b60208082526033908201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604082015272666572207769746820746f6b656e20696e666f60681b606082015260800190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b60208082526018908201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60208082526023908201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736040820152623332b960e91b606082015260800190565b60208082526016908201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604082015260600190565b8151516080820190600d81106200272c57fe5b80835250602083015160018060a01b03808216602085015280604086015116604085015250506060830151606083015292915050565b60405181810167ffffffffffffffff811182821017156200278257600080fd5b604052919050565b600080858511156200279a578182fd5b83861115620027a7578182fd5b5050820193919092039150565b60005b83811015620027d1578181015183820152602001620027b7565b83811115620027e1576000848401525b50505050565b6001600160a01b03811681146200139d57600080fdfe60806040523480156200001157600080fd5b506040516200344538038062003445833981810160405260408110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b50604052505050620001b46200022760201b620012c81760201c565b620001cb8282620002e560201b620013791760201c565b620001e0620003b160201b620014361760201c565b620001fb600080516020620034258339815191528062000459565b6200021f6000805160206200342583398151915262000219620004ab565b620004af565b50506200094a565b600054610100900460ff168062000243575062000243620004bf565b8062000252575060005460ff16155b6200028f5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620002bb576000805460ff1961ff0019909116610100171660011790555b620002c5620004dd565b620002cf620004dd565b8015620002e2576000805461ff00191690555b50565b600054610100900460ff168062000301575062000301620004bf565b8062000310575060005460ff16155b6200034d5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000379576000805460ff1961ff0019909116610100171660011790555b62000383620004dd565b6200038d62000585565b6200039983836200062b565b8015620003ac576000805461ff00191690555b505050565b600054610100900460ff1680620003cd5750620003cd620004bf565b80620003dc575060005460ff16155b620004195760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000445576000805460ff1961ff0019909116610100171660011790555b6200044f620004dd565b620002c562000585565b600082815260336020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526033602052604090912060020155565b3390565b620004bb828262000721565b5050565b6000620004d7306200079c60201b620014d31760201c565b15905090565b600054610100900460ff1680620004f95750620004f9620004bf565b8062000508575060005460ff16155b620005455760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620002cf576000805460ff1961ff0019909116610100171660011790558015620002e2576000805461ff001916905550565b600054610100900460ff1680620005a15750620005a1620004bf565b80620005b0575060005460ff16155b620005ed5760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff1615801562000619576000805460ff1961ff0019909116610100171660011790555b620002cf6301ffc9a760e01b620007a2565b600054610100900460ff168062000647575062000647620004bf565b8062000656575060005460ff16155b620006935760405162461bcd60e51b815260040180806020018281038252602e815260200180620033f7602e913960400191505060405180910390fd5b600054610100900460ff16158015620006bf576000805460ff1961ff0019909116610100171660011790555b8251620006d490609c906020860190620008ae565b508151620006ea90609d906020850190620008ae565b50620006fd6380ac58cd60e01b620007a2565b6200070f635b5e139f60e01b620007a2565b6200039963780e9d6360e01b620007a2565b600082815260336020908152604090912062000748918390620014d962000827821b17901c565b15620004bb5762000758620004ab565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b3b151590565b6001600160e01b0319808216141562000802576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b60006200083e836001600160a01b03841662000847565b90505b92915050565b600062000855838362000896565b6200088d5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000841565b50600062000841565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620008f157805160ff191683800117855562000921565b8280016001018555821562000921579182015b828111156200092157825182559160200191906001019062000904565b506200092f92915062000933565b5090565b5b808211156200092f576000815560010162000934565b612a9d806200095a6000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80634f6ccce711610104578063a217fddf116100a2578063ca15c87311610071578063ca15c873146106b2578063d5391393146106cf578063d547741f146106d7578063e985e9c514610703576101cf565b8063a217fddf14610599578063a22cb465146105a1578063b88d4fde146105cf578063c87b56dd14610695576101cf565b806370a08231116100de57806370a082311461051c5780639010d07c1461054257806391d148541461056557806395d89b4114610591576101cf565b80634f6ccce7146104da5780636352211e146104f75780636c0360eb14610514576101cf565b8063248a9ca31161017157806336568abe1161014b57806336568abe1461042f57806340c10f191461045b57806342842e0e1461048757806342966c68146104bd576101cf565b8063248a9ca3146103ba5780632f2ff15d146103d75780632f745c5914610403576101cf565b8063095ea7b3116101ad578063095ea7b3146102c5578063162094c4146102f357806318160ddd1461036a57806323b872dd14610384576101cf565b806301ffc9a7146101d457806306fdde031461020f578063081812fc1461028c575b600080fd5b6101fb600480360360208110156101ea57600080fd5b50356001600160e01b031916610731565b604080519115158252519081900360200190f35b610217610754565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610251578181015183820152602001610239565b50505050905090810190601f16801561027e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102a9600480360360208110156102a257600080fd5b50356107ea565b604080516001600160a01b039092168252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b506001600160a01b03813516906020013561084c565b005b6101fb6004803603604081101561030957600080fd5b8135919081019060408101602082013564010000000081111561032b57600080fd5b82018360208201111561033d57600080fd5b8035906020019184600183028401116401000000008311171561035f57600080fd5b509092509050610927565b610372610a21565b60408051918252519081900360200190f35b6102f16004803603606081101561039a57600080fd5b506001600160a01b03813581169160208101359091169060400135610a32565b610372600480360360208110156103d057600080fd5b5035610a89565b6102f1600480360360408110156103ed57600080fd5b50803590602001356001600160a01b0316610a9e565b6103726004803603604081101561041957600080fd5b506001600160a01b038135169060200135610b0a565b6102f16004803603604081101561044557600080fd5b50803590602001356001600160a01b0316610b35565b6102f16004803603604081101561047157600080fd5b506001600160a01b038135169060200135610b96565b6102f16004803603606081101561049d57600080fd5b506001600160a01b03813581169160208101359091169060400135610c16565b6102f1600480360360208110156104d357600080fd5b5035610c31565b610372600480360360208110156104f057600080fd5b5035610c83565b6102a96004803603602081101561050d57600080fd5b5035610c99565b610217610cc1565b6103726004803603602081101561053257600080fd5b50356001600160a01b0316610d22565b6102a96004803603604081101561055857600080fd5b5080359060200135610d8a565b6101fb6004803603604081101561057b57600080fd5b50803590602001356001600160a01b0316610da2565b610217610dba565b610372610e1b565b6102f1600480360360408110156105b757600080fd5b506001600160a01b0381351690602001351515610e20565b6102f1600480360360808110156105e557600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561062057600080fd5b82018360208201111561063257600080fd5b8035906020019184600183028401116401000000008311171561065457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f25945050505050565b610217600480360360208110156106ab57600080fd5b5035610f83565b610372600480360360208110156106c857600080fd5b5035611206565b61037261121d565b6102f1600480360360408110156106ed57600080fd5b50803590602001356001600160a01b0316611241565b6101fb6004803603604081101561071957600080fd5b506001600160a01b038135811691602001351661129a565b6001600160e01b0319811660009081526065602052604090205460ff165b919050565b609c8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b820191906000526020600020905b8154815290600101906020018083116107c357829003601f168201915b5050505050905090565b60006107f5826114ee565b6108305760405162461bcd60e51b815260040180806020018281038252602c815260200180612907602c913960400191505060405180910390fd5b506000908152609a60205260409020546001600160a01b031690565b600061085782610c99565b9050806001600160a01b0316836001600160a01b031614156108aa5760405162461bcd60e51b81526004018080602001828103825260218152602001806129b76021913960400191505060405180910390fd5b806001600160a01b03166108bc6114fb565b6001600160a01b031614806108dd57506108dd816108d86114fb565b61129a565b6109185760405162461bcd60e51b815260040180806020018281038252603881526020018061282c6038913960400191505060405180910390fd5b61092283836114ff565b505050565b6000610932846114ee565b61097b576040805162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b604482015290519081900360640190fd5b610985338561156d565b6109d6576040805162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e2055524900000000604482015290519081900360640190fd5b610a168484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061161192505050565b5060015b9392505050565b6000610a2d6098611674565b905090565b610a43610a3d6114fb565b8261156d565b610a7e5760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b61092283838361167f565b60009081526033602052604090206002015490565b600082815260336020526040902060020154610ac190610abc6114fb565b610da2565b610afc5760405162461bcd60e51b815260040180806020018281038252602f81526020018061274b602f913960400191505060405180910390fd5b610b0682826117cb565b5050565b6001600160a01b0382166000908152609760205260408120610b2c9083611834565b90505b92915050565b610b3d6114fb565b6001600160a01b0316816001600160a01b031614610b8c5760405162461bcd60e51b815260040180806020018281038252602f815260200180612a39602f913960400191505060405180910390fd5b610b068282611840565b610bc27f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610abc6114fb565b610c0c576040805162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b604482015290519081900360640190fd5b610b0682826118a9565b61092283838360405180602001604052806000815250610f25565b610c3c610a3d6114fb565b610c775760405162461bcd60e51b8152600401808060200182810382526030815260200180612a096030913960400191505060405180910390fd5b610c80816119d7565b50565b600080610c91609884611aa4565b509392505050565b6000610b2f8260405180606001604052806029815260200161288e6029913960989190611ac0565b609f8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b60006001600160a01b038216610d695760405162461bcd60e51b815260040180806020018281038252602a815260200180612864602a913960400191505060405180910390fd5b6001600160a01b0382166000908152609760205260409020610b2f90611674565b6000828152603360205260408120610b2c9083611834565b6000828152603360205260408120610b2c9083611acd565b609d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107e05780601f106107b5576101008083540402835291602001916107e0565b600081565b610e286114fb565b6001600160a01b0316826001600160a01b03161415610e8e576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80609b6000610e9b6114fb565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610edf6114fb565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b610f36610f306114fb565b8361156d565b610f715760405162461bcd60e51b81526004018080602001828103825260318152602001806129d86031913960400191505060405180910390fd5b610f7d84848484611ae2565b50505050565b6060610f8e826114ee565b610fc95760405162461bcd60e51b815260040180806020018281038252602f815260200180612988602f913960400191505060405180910390fd5b6000828152609e602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084526060939283018282801561105e5780601f106110335761010080835404028352916020019161105e565b820191906000526020600020905b81548152906001019060200180831161104157829003601f168201915b50505050509050606061106f610cc1565b90508051600014156110835750905061074f565b8151156111445780826040516020018083805190602001908083835b602083106110be5780518252601f19909201916020918201910161109f565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111065780518252601f1990920191602091820191016110e7565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061074f565b8061114e85611b34565b6040516020018083805190602001908083835b602083106111805780518252601f199092019160209182019101611161565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b602083106111c85780518252601f1990920191602091820191016111a9565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b6000818152603360205260408120610b2f90611674565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b60008281526033602052604090206002015461125f90610abc6114fb565b610b8c5760405162461bcd60e51b81526004018080602001828103825260308152602001806127fc6030913960400191505060405180910390fd5b6001600160a01b039182166000908152609b6020908152604080832093909416825291909152205460ff1690565b600054610100900460ff16806112e157506112e1611c0f565b806112ef575060005460ff16155b61132a5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611355576000805460ff1961ff0019909116610100171660011790555b61135d611c20565b611365611c20565b8015610c80576000805461ff001916905550565b600054610100900460ff16806113925750611392611c0f565b806113a0575060005460ff16155b6113db5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611406576000805460ff1961ff0019909116610100171660011790555b61140e611c20565b611416611cc0565b6114208383611d5d565b8015610922576000805461ff0019169055505050565b600054610100900460ff168061144f575061144f611c0f565b8061145d575060005460ff16155b6114985760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff161580156114c3576000805460ff1961ff0019909116610100171660011790555b6114cb611c20565b61135d611cc0565b3b151590565b6000610b2c836001600160a01b038416611e42565b6000610b2f609883611e8c565b3390565b6000818152609a6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061153482610c99565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611578826114ee565b6115b35760405162461bcd60e51b815260040180806020018281038252602c8152602001806127d0602c913960400191505060405180910390fd5b60006115be83610c99565b9050806001600160a01b0316846001600160a01b031614806115f95750836001600160a01b03166115ee846107ea565b6001600160a01b0316145b806116095750611609818561129a565b949350505050565b61161a826114ee565b6116555760405162461bcd60e51b815260040180806020018281038252602c815260200180612933602c913960400191505060405180910390fd5b6000828152609e60209081526040909120825161092292840190612655565b6000610b2f82611e98565b826001600160a01b031661169282610c99565b6001600160a01b0316146116d75760405162461bcd60e51b815260040180806020018281038252602981526020018061295f6029913960400191505060405180910390fd5b6001600160a01b03821661171c5760405162461bcd60e51b81526004018080602001828103825260248152602001806127ac6024913960400191505060405180910390fd5b611727838383610922565b6117326000826114ff565b6001600160a01b03831660009081526097602052604090206117549082611e9c565b506001600160a01b03821660009081526097602052604090206117779082611ea8565b5061178460988284611eb4565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526033602052604090206117e390826114d9565b15610b06576117f06114fb565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610b2c8383611eca565b60008281526033602052604090206118589082611f2e565b15610b06576118656114fb565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038216611904576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61190d816114ee565b1561195f576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b61196b60008383610922565b6001600160a01b038216600090815260976020526040902061198d9082611ea8565b5061199a60988284611eb4565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006119e282610c99565b90506119f081600084610922565b6119fb6000836114ff565b6000828152609e60205260409020546002600019610100600184161502019091160415611a39576000828152609e60205260408120611a39916126d3565b6001600160a01b0381166000908152609760205260409020611a5b9083611e9c565b50611a67609883611f43565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000808080611ab38686611f4f565b9097909650945050505050565b6000611609848484611fca565b6000610b2c836001600160a01b038416612094565b611aed84848461167f565b611af9848484846120ac565b610f7d5760405162461bcd60e51b815260040180806020018281038252603281526020018061277a6032913960400191505060405180910390fd5b606081611b5957506040805180820190915260018152600360fc1b602082015261074f565b8160005b8115611b7157600101600a82049150611b5d565b60608167ffffffffffffffff81118015611b8a57600080fd5b506040519080825280601f01601f191660200182016040528015611bb5576020820181803683370190505b50859350905060001982015b8315611c0657600a840660300160f81b82828060019003935081518110611be457fe5b60200101906001600160f81b031916908160001a905350600a84049350611bc1565b50949350505050565b6000611c1a306114d3565b15905090565b600054610100900460ff1680611c395750611c39611c0f565b80611c47575060005460ff16155b611c825760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611365576000805460ff1961ff0019909116610100171660011790558015610c80576000805461ff001916905550565b600054610100900460ff1680611cd95750611cd9611c0f565b80611ce7575060005460ff16155b611d225760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611d4d576000805460ff1961ff0019909116610100171660011790555b6113656301ffc9a760e01b612214565b600054610100900460ff1680611d765750611d76611c0f565b80611d84575060005460ff16155b611dbf5760405162461bcd60e51b815260040180806020018281038252602e8152602001806128b7602e913960400191505060405180910390fd5b600054610100900460ff16158015611dea576000805460ff1961ff0019909116610100171660011790555b8251611dfd90609c906020860190612655565b508151611e1190609d906020850190612655565b50611e226380ac58cd60e01b612214565b611e32635b5e139f60e01b612214565b61142063780e9d6360e01b612214565b6000611e4e8383612094565b611e8457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b2f565b506000610b2f565b6000610b2c8383612094565b5490565b6000610b2c8383612298565b6000610b2c8383611e42565b600061160984846001600160a01b03851661235e565b81546000908210611f0c5760405162461bcd60e51b81526004018080602001828103825260228152602001806127296022913960400191505060405180910390fd5b826000018281548110611f1b57fe5b9060005260206000200154905092915050565b6000610b2c836001600160a01b038416612298565b6000610b2c83836123f5565b815460009081908310611f935760405162461bcd60e51b81526004018080602001828103825260228152602001806128e56022913960400191505060405180910390fd5b6000846000018481548110611fa457fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816120655760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561202a578181015183820152602001612012565b50505050905090810190601f1680156120575780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061207857fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b60006120c0846001600160a01b03166114d3565b6120cc57506001611609565b60606121da630a85bd0160e11b6120e16114fb565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612148578181015183820152602001612130565b50505050905090810190601f1680156121755780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161277a603291396001600160a01b03881691906124c9565b905060008180602001905160208110156121f357600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160e01b03198082161415612273576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152606560205260409020805460ff19166001179055565b6000818152600183016020526040812054801561235457835460001980830191908101906000908790839081106122cb57fe5b90600052602060002001549050808760000184815481106122e857fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061231857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b2f565b6000915050610b2f565b6000828152600184016020526040812054806123c3575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055610a1a565b828560000160018303815481106123d657fe5b9060005260206000209060020201600101819055506000915050610a1a565b60008181526001830160205260408120548015612354578354600019808301919081019060009087908390811061242857fe5b906000526020600020906002020190508087600001848154811061244857fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908061248757fe5b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610b2f9350505050565b60606116098484600085856124dd856114d3565b61252e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061256d5780518252601f19909201916020918201910161254e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146125cf576040519150601f19603f3d011682016040523d82523d6000602084013e6125d4565b606091505b50915091506125e48282866125ef565b979650505050505050565b606083156125fe575081610a1a565b82511561260e5782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561202a578181015183820152602001612012565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061269657805160ff19168380011785556126c3565b828001600101855582156126c3579182015b828111156126c35782518255916020019190600101906126a8565b506126cf929150612713565b5090565b50805460018160011615610100020316600290046000825580601f106126f95750610c80565b601f016020900490600052602060002090810190610c8091905b5b808211156126cf576000815560010161271456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732314d657461646174613a2055524920736574206f66206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732314275726e61626c653a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212206cfed4af0d06c86fc24af2eff048829ddbcce69495200e80936dbbfb68bcbc3964736f6c634300060c0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65649f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba26469706673582212203dcb732cfab6450457532ede4a1839d6b27deedb542d9b799556400ffd8941ff64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerEth.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerEth.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerEth.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerEth.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerEth.json new file mode 100644 index 000000000..dc9f032d5 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerEth.json @@ -0,0 +1,632 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerEth", + "sourceName": "contracts/schain/TokenManagers/TokenManagerEth.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract CommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ethErc20", + "outputs": [ + { + "internalType": "contract EthErc20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exitToMain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + }, + { + "internalType": "contract EthErc20", + "name": "ethErc20Address", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract MessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract TokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract CommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract MessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract EthErc20", + "name": "newEthErc20Address", + "type": "address" + } + ], + "name": "setEthErc20Address", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract TokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferToSchain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50611fca806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638182e7071161010f578063c0e312dc116100a2578063d547741f11610071578063d547741f146103b9578063dec2deb6146103cc578063e4a9eaaf146103d4578063edcc12b5146103e7576101f0565b8063c0e312dc14610378578063ca15c8731461038b578063cb703bff1461039e578063cc5b715b146103b1576101f0565b806391d14854116100de57806391d148541461034d57806392d7846a14610360578063a217fddf14610368578063b9581c5014610370576101f0565b80638182e70714610301578063884cee5a146103145780638b71b4b5146103275780639010d07c1461033a576101f0565b80633b690b6b116101875780636ce681d2116101565780636ce681d2146102cb5780636d611286146102de5780636d6c68e6146102e657806372838baa146102ee576101f0565b80633b690b6b1461029e5780633fa194ce146102a657806350f44280146102ae5780635573b8b6146102c3576101f0565b80632dc151de116101c35780632dc151de146102505780632f2ff15d1461025857806336568abe1461026b57806339927cf91461027e576101f0565b8063029996b8146101f55780630f1a8f74146101ff578063248a9ca31461022857806328c5e18214610248575b600080fd5b6101fd6103fa565b005b61021261020d3660046115d4565b61044c565b60405161021f9190611985565b60405180910390f35b61023b6102363660046115d4565b610467565b60405161021f91906119bd565b61023b61047c565b6102126104c5565b6101fd6102663660046115ec565b6104d4565b6101fd6102793660046115ec565b61051c565b61029161028c3660046116b1565b61055e565b60405161021f91906119b2565b61023b6105bb565b61023b6105c1565b6102b66105d3565b60405161021f91906119c6565b6102126105f6565b6101fd6102d936600461179e565b610605565b610212610758565b610212610767565b6101fd6102fc366004611746565b610776565b6101fd61030f366004611826565b6108e9565b61029161032236600461161b565b61099a565b6101fd61033536600461158d565b610b25565b610212610348366004611675565b610b9c565b61029161035b3660046115ec565b610bbb565b610212610bd3565b61023b610be2565b6101fd610be7565b6101fd6103863660046116b1565b610c2a565b61023b6103993660046115d4565b610ce7565b6101fd6103ac3660046116f1565b610cfe565b61023b610df2565b6101fd6103c73660046115ec565b610e16565b610291610e50565b6101fd6103e23660046115a9565b610e60565b6101fd6103f536600461158d565b610f60565b610412600080516020611f7583398151915233610bbb565b6104375760405162461bcd60e51b815260040161042e90611bd4565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016104ac9190611969565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b6000828152603360205260409020600201546104f29061035b610fa9565b61050e5760405162461bcd60e51b815260040161042e90611a90565b6105188282610fad565b5050565b610524610fa9565b6001600160a01b0316816001600160a01b0316146105545760405162461bcd60e51b815260040161042e90611e59565b6105188282611016565b6000806001600160a01b0316606a60008585604051602001610581929190611959565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b60685481565b600080516020611f7583398151915281565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b600054610100900460ff168061061e575061061e61107f565b8061062c575060005460ff16155b6106485760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff16158015610673576000805460ff1961ff0019909116610100171660011790555b61067b611090565b61068660003361050e565b61069e600080516020611f758339815191523361050e565b6106c87ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83361050e565b856040516020016106d99190611969565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b031992831617909255606680548784169083161790556067805486841690831617905560698054928516929091169190911790558015610750576000805461ff00191690555b505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b6000836040516020016107899190611969565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b8483015291519193506107c9929101611969565b604051602081830303815290604052805190602001208114156107fe5760405162461bcd60e51b815260040161042e90611b4d565b6000818152606a60205260409020546001600160a01b03166108325760405162461bcd60e51b815260040161042e90611a17565b6001600160a01b0383166108585760405162461bcd60e51b815260040161042e90611d2f565b6108623383611123565b6065546000828152606a60205260409020546001600160a01b03918216916365e3781f91879116610893878761115b565b6040518463ffffffff1660e01b81526004016108b1939291906119d9565b600060405180830381600087803b1580156108cb57600080fd5b505af11580156108df573d6000803e3d6000fd5b5050505050505050565b600054610100900460ff1680610902575061090261107f565b80610910575060005460ff16155b61092c5760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff16158015610957576000805460ff1961ff0019909116610100171660011790555b6109648787878787610605565b606b80546001600160a01b0319166001600160a01b0384161790558015610991576000805461ff00191690555b50505050505050565b6065546000906001600160a01b031633146109c75760405162461bcd60e51b815260040161042e90611adf565b6068548514158015610a5457506040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610a049190611969565b604051602081830303815290604052805190602001208514610a42576000858152606a60205260409020546001600160a01b03858116911614610a54565b6069546001600160a01b038581169116145b610a705760405162461bcd60e51b815260040161042e90611d90565b610a78611495565b610a8284846111be565b60208101519091506001600160a01b038116610ab05760405162461bcd60e51b815260040161042e90611dfe565b606b5460408084015190516340c10f1960e01b81526001600160a01b03909216916340c10f1991610ae691859190600401611999565b600060405180830381600087803b158015610b0057600080fd5b505af1158015610b14573d6000803e3d6000fd5b5060019a9950505050505050505050565b610b30600033610bbb565b610b4c5760405162461bcd60e51b815260040161042e90611e2a565b606b546001600160a01b0382811691161415610b7a5760405162461bcd60e51b815260040161042e90611d66565b606b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152603360205260408120610bb49083611206565b9392505050565b6000828152603360205260408120610bb49083611212565b606b546001600160a01b031681565b600081565b610bff600080516020611f7583398151915233610bbb565b610c1b5760405162461bcd60e51b815260040161042e90611bd4565b6069805460ff60a01b19169055565b6066546001600160a01b0316331480610c495750610c49600033610bbb565b610c655760405162461bcd60e51b815260040161042e90611e2a565b60008282604051602001610c7a929190611959565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b0316610cc75760405162461bcd60e51b815260040161042e90611b9d565b6000908152606a6020526040902080546001600160a01b03191690555050565b60008181526033602052604081206105b590611227565b6066546001600160a01b0316331480610d1d5750610d1d600033610bbb565b610d395760405162461bcd60e51b815260040161042e90611e2a565b60008383604051602001610d4e929190611959565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031615610d9c5760405162461bcd60e51b815260040161042e90611dc7565b6001600160a01b038216610dc25760405162461bcd60e51b815260040161042e90611a17565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b600082815260336020526040902060020154610e349061035b610fa9565b6105545760405162461bcd60e51b815260040161042e90611c15565b606954600160a01b900460ff1681565b6001600160a01b038216610e865760405162461bcd60e51b815260040161042e90611d2f565b610e903382611123565b6067546040516311be333d60e11b81526001600160a01b039091169063237c667a90610ec0908590600401611985565b600060405180830381600087803b158015610eda57600080fd5b505af1158015610eee573d6000803e3d6000fd5b50506065546069546001600160a01b0391821693506365e3781f925016610f15858561115b565b6040518363ffffffff1660e01b8152600401610f32929190611ce8565b600060405180830381600087803b158015610f4c57600080fd5b505af1158015610750573d6000803e3d6000fd5b610f6b600033610bbb565b610f875760405162461bcd60e51b815260040161042e90611b16565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6000828152603360205260409020610fc59082611232565b1561051857610fd2610fa9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260336020526040902061102e9082611247565b156105185761103b610fa9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b600061108a3061125c565b15905090565b600054610100900460ff16806110a957506110a961107f565b806110b7575060005460ff16155b6110d35760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff161580156110fe576000805460ff1961ff0019909116610100171660011790555b611106611262565b61110e611262565b8015611120576000805461ff00191690555b50565b801561051857606b546040516338b5bd8d60e21b81526001600160a01b039091169063e2d6f63490610f329085908590600401611999565b6060611165611495565b604080516080810190915280606081018060018152508152602001856001600160a01b03168152602001848152509050806040516020016111a69190611ea8565b60405160208183030381529060405291505092915050565b6111c6611495565b60016111d284846112e3565b600c8111156111dd57fe5b146111fa5760405162461bcd60e51b815260040161042e90611c65565b610bb4828401846118bf565b6000610bb48383611324565b6000610bb4836001600160a01b038416611369565b60006105b582611381565b6000610bb4836001600160a01b038416611385565b6000610bb4836001600160a01b0384166113cf565b3b151590565b600054610100900460ff168061127b575061127b61107f565b80611289575060005460ff16155b6112a55760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff1615801561110e576000805460ff1961ff0019909116610100171660011790558015611120576000805461ff001916905550565b6000806112f2838501856115d4565b9050602081066113185761131061130b84838188611f07565b6112e3565b9150506105b5565b61131083850185611696565b815460009082106113475760405162461bcd60e51b815260040161042e90611a4e565b82600001828154811061135657fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60006113918383611369565b6113c7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105b5565b5060006105b5565b6000818152600183016020526040812054801561148b578354600019808301919081019060009087908390811061140257fe5b906000526020600020015490508087600001848154811061141f57fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061144f57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506105b5565b60009150506105b5565b60405180606001604052806114a86114bc565b815260006020820181905260409091015290565b60408051602081019091526000815290565b60008083601f8401126114df578182fd5b50813567ffffffffffffffff8111156114f6578182fd5b60208301915083602082850101111561150e57600080fd5b9250929050565b8035600d81106105b557600080fd5b600082601f830112611534578081fd5b813567ffffffffffffffff81111561154a578182fd5b61155d601f8201601f1916602001611ee0565b915080825283602082850101111561157457600080fd5b8060208401602084013760009082016020015292915050565b60006020828403121561159e578081fd5b8135610bb481611f5f565b600080604083850312156115bb578081fd5b82356115c681611f5f565b946020939093013593505050565b6000602082840312156115e5578081fd5b5035919050565b600080604083850312156115fe578182fd5b82359150602083013561161081611f5f565b809150509250929050565b60008060008060608587031215611630578182fd5b84359350602085013561164281611f5f565b9250604085013567ffffffffffffffff81111561165d578283fd5b611669878288016114ce565b95989497509550505050565b60008060408385031215611687578182fd5b50508035926020909101359150565b6000602082840312156116a7578081fd5b610bb48383611515565b600080602083850312156116c3578182fd5b823567ffffffffffffffff8111156116d9578283fd5b6116e5858286016114ce565b90969095509350505050565b600080600060408486031215611705578283fd5b833567ffffffffffffffff81111561171b578384fd5b611727868287016114ce565b909450925050602084013561173b81611f5f565b809150509250925092565b60008060006060848603121561175a578283fd5b833567ffffffffffffffff811115611770578384fd5b61177c86828701611524565b935050602084013561178d81611f5f565b929592945050506040919091013590565b600080600080600060a086880312156117b5578283fd5b853567ffffffffffffffff8111156117cb578384fd5b6117d788828901611524565b95505060208601356117e881611f5f565b935060408601356117f881611f5f565b9250606086013561180881611f5f565b9150608086013561181881611f5f565b809150509295509295909350565b60008060008060008060c0878903121561183e578384fd5b863567ffffffffffffffff811115611854578485fd5b61186089828a01611524565b965050602087013561187181611f5f565b9450604087013561188181611f5f565b9350606087013561189181611f5f565b925060808701356118a181611f5f565b915060a08701356118b181611f5f565b809150509295509295509295565b600081830360608112156118d1578182fd5b6118db6060611ee0565b60208212156118e8578283fd5b6118f26020611ee0565b91506118fe8585611515565b825290815260208301359061191282611f5f565b81602082015260408401356040820152809250505092915050565b60008151808452611945816020860160208601611f2f565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b6000825161197b818460208701611f2f565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b600060208252610bb4602083018461192d565b6000606082526119ec606083018661192d565b6001600160a01b03851660208401528281036040840152611a0d818561192d565b9695505050505050565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f4d6573736167652074797065206973206e6f7420455448207472616e73666572604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600060608252600760608301526613585a5b9b995d60ca1b608083015260018060a01b038416602083015260a06040830152611d2760a083018461192d565b949350505050565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b60208082526010908201526f5468652073616d65206164647265737360801b604082015260600190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b60208082526012908201527124b731b7b93932b1ba103932b1b2b4bb32b960711b604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b8151516060820190600d8110611eba57fe5b82526020838101516001600160a01b031690830152604092830151929091019190915290565b60405181810167ffffffffffffffff81118282101715611eff57600080fd5b604052919050565b60008085851115611f16578182fd5b83861115611f22578182fd5b5050820193919092039150565b60005b83811015611f4a578181015183820152602001611f32565b83811115611f59576000848401525b50505050565b6001600160a01b038116811461112057600080fdfe7164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220efde7fc38a3556c193046d11cb81323fb7f4529a06ea809d112822cf41fede0e64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80638182e7071161010f578063c0e312dc116100a2578063d547741f11610071578063d547741f146103b9578063dec2deb6146103cc578063e4a9eaaf146103d4578063edcc12b5146103e7576101f0565b8063c0e312dc14610378578063ca15c8731461038b578063cb703bff1461039e578063cc5b715b146103b1576101f0565b806391d14854116100de57806391d148541461034d57806392d7846a14610360578063a217fddf14610368578063b9581c5014610370576101f0565b80638182e70714610301578063884cee5a146103145780638b71b4b5146103275780639010d07c1461033a576101f0565b80633b690b6b116101875780636ce681d2116101565780636ce681d2146102cb5780636d611286146102de5780636d6c68e6146102e657806372838baa146102ee576101f0565b80633b690b6b1461029e5780633fa194ce146102a657806350f44280146102ae5780635573b8b6146102c3576101f0565b80632dc151de116101c35780632dc151de146102505780632f2ff15d1461025857806336568abe1461026b57806339927cf91461027e576101f0565b8063029996b8146101f55780630f1a8f74146101ff578063248a9ca31461022857806328c5e18214610248575b600080fd5b6101fd6103fa565b005b61021261020d3660046115d4565b61044c565b60405161021f9190611985565b60405180910390f35b61023b6102363660046115d4565b610467565b60405161021f91906119bd565b61023b61047c565b6102126104c5565b6101fd6102663660046115ec565b6104d4565b6101fd6102793660046115ec565b61051c565b61029161028c3660046116b1565b61055e565b60405161021f91906119b2565b61023b6105bb565b61023b6105c1565b6102b66105d3565b60405161021f91906119c6565b6102126105f6565b6101fd6102d936600461179e565b610605565b610212610758565b610212610767565b6101fd6102fc366004611746565b610776565b6101fd61030f366004611826565b6108e9565b61029161032236600461161b565b61099a565b6101fd61033536600461158d565b610b25565b610212610348366004611675565b610b9c565b61029161035b3660046115ec565b610bbb565b610212610bd3565b61023b610be2565b6101fd610be7565b6101fd6103863660046116b1565b610c2a565b61023b6103993660046115d4565b610ce7565b6101fd6103ac3660046116f1565b610cfe565b61023b610df2565b6101fd6103c73660046115ec565b610e16565b610291610e50565b6101fd6103e23660046115a9565b610e60565b6101fd6103f536600461158d565b610f60565b610412600080516020611f7583398151915233610bbb565b6104375760405162461bcd60e51b815260040161042e90611bd4565b60405180910390fd5b6069805460ff60a01b1916600160a01b179055565b606a602052600090815260409020546001600160a01b031681565b60009081526033602052604090206002015490565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016104ac9190611969565b6040516020818303038152906040528051906020012081565b6066546001600160a01b031681565b6000828152603360205260409020600201546104f29061035b610fa9565b61050e5760405162461bcd60e51b815260040161042e90611a90565b6105188282610fad565b5050565b610524610fa9565b6001600160a01b0316816001600160a01b0316146105545760405162461bcd60e51b815260040161042e90611e59565b6105188282611016565b6000806001600160a01b0316606a60008585604051602001610581929190611959565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b0316141590505b92915050565b60685481565b600080516020611f7583398151915281565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b600054610100900460ff168061061e575061061e61107f565b8061062c575060005460ff16155b6106485760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff16158015610673576000805460ff1961ff0019909116610100171660011790555b61067b611090565b61068660003361050e565b61069e600080516020611f758339815191523361050e565b6106c87ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83361050e565b856040516020016106d99190611969565b60408051601f198184030181529190528051602090910120606855606580546001600160a01b038088166001600160a01b031992831617909255606680548784169083161790556067805486841690831617905560698054928516929091169190911790558015610750576000805461ff00191690555b505050505050565b6069546001600160a01b031681565b6067546001600160a01b031681565b6000836040516020016107899190611969565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b8483015291519193506107c9929101611969565b604051602081830303815290604052805190602001208114156107fe5760405162461bcd60e51b815260040161042e90611b4d565b6000818152606a60205260409020546001600160a01b03166108325760405162461bcd60e51b815260040161042e90611a17565b6001600160a01b0383166108585760405162461bcd60e51b815260040161042e90611d2f565b6108623383611123565b6065546000828152606a60205260409020546001600160a01b03918216916365e3781f91879116610893878761115b565b6040518463ffffffff1660e01b81526004016108b1939291906119d9565b600060405180830381600087803b1580156108cb57600080fd5b505af11580156108df573d6000803e3d6000fd5b5050505050505050565b600054610100900460ff1680610902575061090261107f565b80610910575060005460ff16155b61092c5760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff16158015610957576000805460ff1961ff0019909116610100171660011790555b6109648787878787610605565b606b80546001600160a01b0319166001600160a01b0384161790558015610991576000805461ff00191690555b50505050505050565b6065546000906001600160a01b031633146109c75760405162461bcd60e51b815260040161042e90611adf565b6068548514158015610a5457506040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610a049190611969565b604051602081830303815290604052805190602001208514610a42576000858152606a60205260409020546001600160a01b03858116911614610a54565b6069546001600160a01b038581169116145b610a705760405162461bcd60e51b815260040161042e90611d90565b610a78611495565b610a8284846111be565b60208101519091506001600160a01b038116610ab05760405162461bcd60e51b815260040161042e90611dfe565b606b5460408084015190516340c10f1960e01b81526001600160a01b03909216916340c10f1991610ae691859190600401611999565b600060405180830381600087803b158015610b0057600080fd5b505af1158015610b14573d6000803e3d6000fd5b5060019a9950505050505050505050565b610b30600033610bbb565b610b4c5760405162461bcd60e51b815260040161042e90611e2a565b606b546001600160a01b0382811691161415610b7a5760405162461bcd60e51b815260040161042e90611d66565b606b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152603360205260408120610bb49083611206565b9392505050565b6000828152603360205260408120610bb49083611212565b606b546001600160a01b031681565b600081565b610bff600080516020611f7583398151915233610bbb565b610c1b5760405162461bcd60e51b815260040161042e90611bd4565b6069805460ff60a01b19169055565b6066546001600160a01b0316331480610c495750610c49600033610bbb565b610c655760405162461bcd60e51b815260040161042e90611e2a565b60008282604051602001610c7a929190611959565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b0316610cc75760405162461bcd60e51b815260040161042e90611b9d565b6000908152606a6020526040902080546001600160a01b03191690555050565b60008181526033602052604081206105b590611227565b6066546001600160a01b0316331480610d1d5750610d1d600033610bbb565b610d395760405162461bcd60e51b815260040161042e90611e2a565b60008383604051602001610d4e929190611959565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031615610d9c5760405162461bcd60e51b815260040161042e90611dc7565b6001600160a01b038216610dc25760405162461bcd60e51b815260040161042e90611a17565b6000908152606a6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b600082815260336020526040902060020154610e349061035b610fa9565b6105545760405162461bcd60e51b815260040161042e90611c15565b606954600160a01b900460ff1681565b6001600160a01b038216610e865760405162461bcd60e51b815260040161042e90611d2f565b610e903382611123565b6067546040516311be333d60e11b81526001600160a01b039091169063237c667a90610ec0908590600401611985565b600060405180830381600087803b158015610eda57600080fd5b505af1158015610eee573d6000803e3d6000fd5b50506065546069546001600160a01b0391821693506365e3781f925016610f15858561115b565b6040518363ffffffff1660e01b8152600401610f32929190611ce8565b600060405180830381600087803b158015610f4c57600080fd5b505af1158015610750573d6000803e3d6000fd5b610f6b600033610bbb565b610f875760405162461bcd60e51b815260040161042e90611b16565b606980546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6000828152603360205260409020610fc59082611232565b1561051857610fd2610fa9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260336020526040902061102e9082611247565b156105185761103b610fa9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b600061108a3061125c565b15905090565b600054610100900460ff16806110a957506110a961107f565b806110b7575060005460ff16155b6110d35760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff161580156110fe576000805460ff1961ff0019909116610100171660011790555b611106611262565b61110e611262565b8015611120576000805461ff00191690555b50565b801561051857606b546040516338b5bd8d60e21b81526001600160a01b039091169063e2d6f63490610f329085908590600401611999565b6060611165611495565b604080516080810190915280606081018060018152508152602001856001600160a01b03168152602001848152509050806040516020016111a69190611ea8565b60405160208183030381529060405291505092915050565b6111c6611495565b60016111d284846112e3565b600c8111156111dd57fe5b146111fa5760405162461bcd60e51b815260040161042e90611c65565b610bb4828401846118bf565b6000610bb48383611324565b6000610bb4836001600160a01b038416611369565b60006105b582611381565b6000610bb4836001600160a01b038416611385565b6000610bb4836001600160a01b0384166113cf565b3b151590565b600054610100900460ff168061127b575061127b61107f565b80611289575060005460ff16155b6112a55760405162461bcd60e51b815260040161042e90611c9a565b600054610100900460ff1615801561110e576000805460ff1961ff0019909116610100171660011790558015611120576000805461ff001916905550565b6000806112f2838501856115d4565b9050602081066113185761131061130b84838188611f07565b6112e3565b9150506105b5565b61131083850185611696565b815460009082106113475760405162461bcd60e51b815260040161042e90611a4e565b82600001828154811061135657fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60006113918383611369565b6113c7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105b5565b5060006105b5565b6000818152600183016020526040812054801561148b578354600019808301919081019060009087908390811061140257fe5b906000526020600020015490508087600001848154811061141f57fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061144f57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506105b5565b60009150506105b5565b60405180606001604052806114a86114bc565b815260006020820181905260409091015290565b60408051602081019091526000815290565b60008083601f8401126114df578182fd5b50813567ffffffffffffffff8111156114f6578182fd5b60208301915083602082850101111561150e57600080fd5b9250929050565b8035600d81106105b557600080fd5b600082601f830112611534578081fd5b813567ffffffffffffffff81111561154a578182fd5b61155d601f8201601f1916602001611ee0565b915080825283602082850101111561157457600080fd5b8060208401602084013760009082016020015292915050565b60006020828403121561159e578081fd5b8135610bb481611f5f565b600080604083850312156115bb578081fd5b82356115c681611f5f565b946020939093013593505050565b6000602082840312156115e5578081fd5b5035919050565b600080604083850312156115fe578182fd5b82359150602083013561161081611f5f565b809150509250929050565b60008060008060608587031215611630578182fd5b84359350602085013561164281611f5f565b9250604085013567ffffffffffffffff81111561165d578283fd5b611669878288016114ce565b95989497509550505050565b60008060408385031215611687578182fd5b50508035926020909101359150565b6000602082840312156116a7578081fd5b610bb48383611515565b600080602083850312156116c3578182fd5b823567ffffffffffffffff8111156116d9578283fd5b6116e5858286016114ce565b90969095509350505050565b600080600060408486031215611705578283fd5b833567ffffffffffffffff81111561171b578384fd5b611727868287016114ce565b909450925050602084013561173b81611f5f565b809150509250925092565b60008060006060848603121561175a578283fd5b833567ffffffffffffffff811115611770578384fd5b61177c86828701611524565b935050602084013561178d81611f5f565b929592945050506040919091013590565b600080600080600060a086880312156117b5578283fd5b853567ffffffffffffffff8111156117cb578384fd5b6117d788828901611524565b95505060208601356117e881611f5f565b935060408601356117f881611f5f565b9250606086013561180881611f5f565b9150608086013561181881611f5f565b809150509295509295909350565b60008060008060008060c0878903121561183e578384fd5b863567ffffffffffffffff811115611854578485fd5b61186089828a01611524565b965050602087013561187181611f5f565b9450604087013561188181611f5f565b9350606087013561189181611f5f565b925060808701356118a181611f5f565b915060a08701356118b181611f5f565b809150509295509295509295565b600081830360608112156118d1578182fd5b6118db6060611ee0565b60208212156118e8578283fd5b6118f26020611ee0565b91506118fe8585611515565b825290815260208301359061191282611f5f565b81602082015260408401356040820152809250505092915050565b60008151808452611945816020860160208601611f2f565b601f01601f19169290920160200192915050565b6000828483379101908152919050565b6000825161197b818460208701611f2f565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b600060208252610bb4602083018461192d565b6000606082526119ec606083018661192d565b6001600160a01b03851660208401528281036040840152611a0d818561192d565b9695505050505050565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252601c908201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604082015260600190565b6020808252601e908201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604082015260600190565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b60208082526018908201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604082015260600190565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b6020808252818101527f4d6573736167652074797065206973206e6f7420455448207472616e73666572604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600060608252600760608301526613585a5b9b995d60ca1b608083015260018060a01b038416602083015260a06040830152611d2760a083018461192d565b949350505050565b6020808252601a908201527f496e636f72726563742072656365697665722061646472657373000000000000604082015260600190565b60208082526010908201526f5468652073616d65206164647265737360801b604082015260600190565b6020808252601b908201527f526563656976657220636861696e20697320696e636f72726563740000000000604082015260600190565b6020808252601c908201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604082015260600190565b60208082526012908201527124b731b7b93932b1ba103932b1b2b4bb32b960711b604082015260600190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b8151516060820190600d8110611eba57fe5b82526020838101516001600160a01b031690830152604092830151929091019190915290565b60405181810167ffffffffffffffff81118282101715611eff57600080fd5b604052919050565b60008085851115611f16578182fd5b83861115611f22578182fd5b5050820193919092039150565b60005b83811015611f4a578181015183820152602001611f32565b83811115611f59576000848401525b50505050565b6001600160a01b038116811461112057600080fdfe7164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220efde7fc38a3556c193046d11cb81323fb7f4529a06ea809d112822cf41fede0e64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerLinker.dbg.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerLinker.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerLinker.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerLinker.json b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerLinker.json new file mode 100644 index 000000000..da82ccba6 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/artifacts/TokenManagerLinker.json @@ -0,0 +1,491 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerLinker", + "sourceName": "contracts/schain/TokenManagerLinker.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isAllowed", + "type": "bool" + } + ], + "name": "InterchainConnectionAllowed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address[]", + "name": "tokenManagerAddresses", + "type": "address[]" + } + ], + "name": "connectSchain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "disconnectSchain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasSchain", + "outputs": [ + { + "internalType": "bool", + "name": "connected", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TokenManager", + "name": "tokenManager", + "type": "address" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMessageProxy", + "name": "newMessageProxyAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "linker", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "interchainConnections", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "linkerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TokenManager", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "registerTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TokenManager", + "name": "tokenManagerAddress", + "type": "address" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "contract TokenManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50611b09806100206000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80635573b8b6116100c3578063b4fd8e141161007c578063b4fd8e1414610292578063b9727f96146102a5578063ca15c873146102b8578063d547741f146102cb578063e953c992146102de578063f68e9553146102f15761014d565b80635573b8b61461024157806364a5142f14610249578063884cee5a146102515780639010d07c1461026457806391d1485414610277578063a217fddf1461028a5761014d565b8063291f60d311610115578063291f60d3146101c05780632f2ff15d146101d357806336568abe146101e657806341ecadf9146101f9578063485cc9551461021957806350f442801461022c5761014d565b8063041f4c9b146101525780630f4ef5fd1461017b578063173df64b14610183578063248a9ca31461019857806328c5e182146101b8575b600080fd5b6101656101603660046113f3565b6102f9565b6040516101729190611582565b60405180910390f35b610165610447565b6101966101913660046113f3565b610450565b005b6101ab6101a63660046112e9565b61058b565b604051610172919061158d565b6101ab6105a3565b6101966101ce3660046112aa565b6105ec565b6101966101e1366004611301565b610672565b6101966101f4366004611301565b6106ba565b61020c6102073660046112e9565b6106fc565b604051610172919061156e565b6101966102273660046113ab565b610723565b610234610803565b60405161017291906115d6565b61020c610826565b61020c610835565b61016561025f366004611330565b610844565b61020c61027236600461138a565b6109d5565b610165610285366004611301565b6109f6565b6101ab610a0e565b6101966102a0366004611433565b610a13565b6101966102b33660046112aa565b610ba6565b6101ab6102c63660046112e9565b610ce3565b6101966102d9366004611301565b610cfa565b6101656102ec3660046112aa565b610d34565b6101ab610d97565b60675460019060005b818110156103b4578280156103aa57506067818154811061031f57fe5b6000918252602090912001546040516339927cf960e01b81526001600160a01b03909116906339927cf99061035a9088908890600401611596565b60206040518083038186803b15801561037257600080fd5b505afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa91906112cd565b9250600101610302565b5081801561043f5750606554604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa906103ef9087908790600401611596565b60206040518083038186803b15801561040757600080fd5b505afa15801561041b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043f91906112cd565b949350505050565b60685460ff1681565b610468600080516020611ab4833981519152336109f6565b61048d5760405162461bcd60e51b815260040161048490611718565b60405180910390fd5b60675460005b8181101561052157606781815481106104a857fe5b600091825260209091200154604051633038c4b760e21b81526001600160a01b039091169063c0e312dc906104e39087908790600401611596565b600060405180830381600087803b1580156104fd57600080fd5b505af1158015610511573d6000803e3d6000fd5b5050600190920191506104939050565b50606554604051633cdd2cc360e01b81526001600160a01b0390911690633cdd2cc3906105549086908690600401611596565b600060405180830381600087803b15801561056e57600080fd5b505af1158015610582573d6000803e3d6000fd5b50505050505050565b6000818152603360205260409020600201545b919050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016105d39190611552565b6040516020818303038152906040528051906020012081565b610604600080516020611ab4833981519152336109f6565b6106205760405162461bcd60e51b815260040161048490611718565b606780546001810182556000919091527f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0180546001600160a01b0319166001600160a01b0392909216919091179055565b60008281526033602052604090206002015461069090610285610da9565b6106ac5760405162461bcd60e51b81526004016104849061164b565b6106b68282610dad565b5050565b6106c2610da9565b6001600160a01b0316816001600160a01b0316146106f25760405162461bcd60e51b8152600401610484906119c2565b6106b68282610e16565b6067818154811061070957fe5b6000918252602090912001546001600160a01b0316905081565b600054610100900460ff168061073c575061073c610e7f565b8061074a575060005460ff16155b6107665760405162461bcd60e51b815260040161048490611876565b600054610100900460ff16158015610791576000805460ff1961ff0019909116610100171660011790555b610799610e90565b6107a46000336106ac565b6107bc600080516020611ab4833981519152336106ac565b606580546001600160a01b038086166001600160a01b031992831617909255606680549285169290911691909117905580156107fe576000805461ff00191690555b505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b6066546001600160a01b031681565b6065546000906001600160a01b031633146108715760405162461bcd60e51b81526004016104849061198b565b6066546001600160a01b0385811691161461089e5760405162461bcd60e51b81526004016104849061169a565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016108ce9190611552565b6040516020818303038152906040528051906020012085146109025760405162461bcd60e51b815260040161048490611833565b600061090e8484610f23565b9050600881600c81111561091e57fe5b1461093b5760405162461bcd60e51b81526004016104849061174f565b610943611222565b61094d8585610f64565b6020810151606854919250151560ff9091161515141561097f5760405162461bcd60e51b81526004016104849061193c565b60208101516068805460ff19168215151790556040517fce4347a8c71d04a62f940154f3607d6a42f153b91cb09d9ec71356d2b36beb32916109c091611582565b60405180910390a15060019695505050505050565b60008281526033602052604081206109ed9083610fac565b90505b92915050565b60008281526033602052604081206109ed9083610fb8565b600081565b610a2b600080516020611ab4833981519152336109f6565b610a475760405162461bcd60e51b815260040161048490611718565b60685460ff16610a695760405162461bcd60e51b8152600401610484906118c4565b6067548114610a8a5760405162461bcd60e51b815260040161048490611905565b60005b81811015610b3b5760678181548110610aa257fe5b6000918252602090912001546001600160a01b031663cb703bff8686868686818110610aca57fe5b9050602002016020810190610adf91906112aa565b6040518463ffffffff1660e01b8152600401610afd939291906115aa565b600060405180830381600087803b158015610b1757600080fd5b505af1158015610b2b573d6000803e3d6000fd5b505060019092019150610a8d9050565b5060655460405163f2f6360560e01b81526001600160a01b039091169063f2f6360590610b6e9087908790600401611596565b600060405180830381600087803b158015610b8857600080fd5b505af1158015610b9c573d6000803e3d6000fd5b5050505050505050565b610bbe600080516020611ab4833981519152336109f6565b610bda5760405162461bcd60e51b815260040161048490611718565b6067546000905b80821015610c2b57826001600160a01b031660678381548110610c0057fe5b6000918252602090912001546001600160a01b03161415610c2057610c2b565b600190910190610be1565b808210156107fe57610c3e816001610fcd565b821015610cb1576067610c52826001610fcd565b81548110610c5c57fe5b600091825260209091200154606780546001600160a01b039092169184908110610c8257fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6067805480610cbc57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b60008181526033602052604081206109f090610ff5565b600082815260336020526040902060020154610d1890610285610da9565b6106f25760405162461bcd60e51b8152600401610484906117e3565b60675460009081905b80821015610d8d57836001600160a01b031660678381548110610d5c57fe5b6000918252602090912001546001600160a01b03161415610d825760019250505061059e565b600190910190610d3d565b5060009392505050565b600080516020611ab483398151915281565b3390565b6000828152603360205260409020610dc59082611000565b156106b657610dd2610da9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020610e2e9082611015565b156106b657610e3b610da9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000610e8a3061102a565b15905090565b600054610100900460ff1680610ea95750610ea9610e7f565b80610eb7575060005460ff16155b610ed35760405162461bcd60e51b815260040161048490611876565b600054610100900460ff16158015610efe576000805460ff1961ff0019909116610100171660011790555b610f06611030565b610f0e611030565b8015610f20576000805461ff00191690555b50565b600080610f32838501856112e9565b905060208106610f5857610f50610f4b84838188611a38565b610f23565b9150506109f0565b610f50838501856113d8565b610f6c611222565b6008610f788484610f23565b600c811115610f8357fe5b14610fa05760405162461bcd60e51b8152600401610484906116cf565b6109ed828401846114c6565b60006109ed83836110b1565b60006109ed836001600160a01b0384166110f6565b600082821115610fef5760405162461bcd60e51b8152600401610484906117ac565b50900390565b60006109f08261110e565b60006109ed836001600160a01b038416611112565b60006109ed836001600160a01b03841661115c565b3b151590565b600054610100900460ff16806110495750611049610e7f565b80611057575060005460ff16155b6110735760405162461bcd60e51b815260040161048490611876565b600054610100900460ff16158015610f0e576000805460ff1961ff0019909116610100171660011790558015610f20576000805461ff001916905550565b815460009082106110d45760405162461bcd60e51b815260040161048490611609565b8260000182815481106110e357fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b600061111e83836110f6565b611154575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109f0565b5060006109f0565b60008181526001830160205260408120548015611218578354600019808301919081019060009087908390811061118f57fe5b90600052602060002001549050808760000184815481106111ac57fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806111dc57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506109f0565b60009150506109f0565b6040518060400160405280611235611242565b8152600060209091015290565b60408051602081019091526000815290565b60008083601f840112611265578182fd5b50813567ffffffffffffffff81111561127c578182fd5b60208301915083602082850101111561129457600080fd5b9250929050565b8035600d81106109f057600080fd5b6000602082840312156112bb578081fd5b81356112c681611a90565b9392505050565b6000602082840312156112de578081fd5b81516112c681611aa5565b6000602082840312156112fa578081fd5b5035919050565b60008060408385031215611313578081fd5b82359150602083013561132581611a90565b809150509250929050565b60008060008060608587031215611345578182fd5b84359350602085013561135781611a90565b9250604085013567ffffffffffffffff811115611372578283fd5b61137e87828801611254565b95989497509550505050565b6000806040838503121561139c578182fd5b50508035926020909101359150565b600080604083850312156113bd578182fd5b82356113c881611a90565b9150602083013561132581611a90565b6000602082840312156113e9578081fd5b6109ed838361129b565b60008060208385031215611405578182fd5b823567ffffffffffffffff81111561141b578283fd5b61142785828601611254565b90969095509350505050565b60008060008060408587031215611448578384fd5b843567ffffffffffffffff8082111561145f578586fd5b61146b88838901611254565b90965094506020870135915080821115611483578384fd5b818701915087601f830112611496578384fd5b8135818111156114a4578485fd5b88602080830285010111156114b7578485fd5b95989497505060200194505050565b600081830360408112156114d8578182fd5b6114e26040611a11565b60208212156114ef578283fd5b6114f96020611a11565b9150611505858561129b565b825290815260208301359061151982611aa5565b60208101919091529392505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008251611564818460208701611a60565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b60006020825261043f602083018486611528565b6000604082526115be604083018587611528565b905060018060a01b0383166020830152949350505050565b60006020825282518060208401526115f5816040850160208701611a60565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252818101527f53656e6465722066726f6d204d61696e6e657420697320696e636f7272656374604082015260600190565b60208082526029908201527f4d6573736167652074797065206973206e6f7420496e746572636861696e206360408201526837b73732b1ba34b7b760b91b606082015260800190565b6020808252601a908201527f5245474953545241525f524f4c45206973207265717569726564000000000000604082015260600190565b60208082526038908201527f546865206d6573736167652073686f756c6420636f6e7461696e206120696e7460408201527f6572636861696e20636f6e6e656374696f6e2073746174650000000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526023908201527f536f7572636520636861696e206e616d652073686f756c64206265204d61696e6040820152621b995d60ea1b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f496e746572636861696e20636f6e6e656374696f6e206e6f7420616c6c6f77656040820152601960fa1b606082015260800190565b6020808252601d908201527f496e636f7272656374206e756d626572206f6620616464726573736573000000604082015260600190565b6020808252602f908201527f496e746572636861696e20636f6e6e656374696f6e2073746174652073686f7560408201526e1b1908189948191a5999995c995b9d608a1b606082015260800190565b6020808252601d908201527f53656e646572206973206e6f742061206d6573736167652070726f7879000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60405181810167ffffffffffffffff81118282101715611a3057600080fd5b604052919050565b60008085851115611a47578182fd5b83861115611a53578182fd5b5050820193919092039150565b60005b83811015611a7b578181015183820152602001611a63565b83811115611a8a576000848401525b50505050565b6001600160a01b0381168114610f2057600080fd5b8015158114610f2057600080fdfeedcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c309238a2646970667358221220b5eb8c3b77cbd30cbf8084a2c674c7f133c5691aa16514e744eed381a945dd0864736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80635573b8b6116100c3578063b4fd8e141161007c578063b4fd8e1414610292578063b9727f96146102a5578063ca15c873146102b8578063d547741f146102cb578063e953c992146102de578063f68e9553146102f15761014d565b80635573b8b61461024157806364a5142f14610249578063884cee5a146102515780639010d07c1461026457806391d1485414610277578063a217fddf1461028a5761014d565b8063291f60d311610115578063291f60d3146101c05780632f2ff15d146101d357806336568abe146101e657806341ecadf9146101f9578063485cc9551461021957806350f442801461022c5761014d565b8063041f4c9b146101525780630f4ef5fd1461017b578063173df64b14610183578063248a9ca31461019857806328c5e182146101b8575b600080fd5b6101656101603660046113f3565b6102f9565b6040516101729190611582565b60405180910390f35b610165610447565b6101966101913660046113f3565b610450565b005b6101ab6101a63660046112e9565b61058b565b604051610172919061158d565b6101ab6105a3565b6101966101ce3660046112aa565b6105ec565b6101966101e1366004611301565b610672565b6101966101f4366004611301565b6106ba565b61020c6102073660046112e9565b6106fc565b604051610172919061156e565b6101966102273660046113ab565b610723565b610234610803565b60405161017291906115d6565b61020c610826565b61020c610835565b61016561025f366004611330565b610844565b61020c61027236600461138a565b6109d5565b610165610285366004611301565b6109f6565b6101ab610a0e565b6101966102a0366004611433565b610a13565b6101966102b33660046112aa565b610ba6565b6101ab6102c63660046112e9565b610ce3565b6101966102d9366004611301565b610cfa565b6101656102ec3660046112aa565b610d34565b6101ab610d97565b60675460019060005b818110156103b4578280156103aa57506067818154811061031f57fe5b6000918252602090912001546040516339927cf960e01b81526001600160a01b03909116906339927cf99061035a9088908890600401611596565b60206040518083038186803b15801561037257600080fd5b505afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa91906112cd565b9250600101610302565b5081801561043f5750606554604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa906103ef9087908790600401611596565b60206040518083038186803b15801561040757600080fd5b505afa15801561041b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043f91906112cd565b949350505050565b60685460ff1681565b610468600080516020611ab4833981519152336109f6565b61048d5760405162461bcd60e51b815260040161048490611718565b60405180910390fd5b60675460005b8181101561052157606781815481106104a857fe5b600091825260209091200154604051633038c4b760e21b81526001600160a01b039091169063c0e312dc906104e39087908790600401611596565b600060405180830381600087803b1580156104fd57600080fd5b505af1158015610511573d6000803e3d6000fd5b5050600190920191506104939050565b50606554604051633cdd2cc360e01b81526001600160a01b0390911690633cdd2cc3906105549086908690600401611596565b600060405180830381600087803b15801561056e57600080fd5b505af1158015610582573d6000803e3d6000fd5b50505050505050565b6000818152603360205260409020600201545b919050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016105d39190611552565b6040516020818303038152906040528051906020012081565b610604600080516020611ab4833981519152336109f6565b6106205760405162461bcd60e51b815260040161048490611718565b606780546001810182556000919091527f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0180546001600160a01b0319166001600160a01b0392909216919091179055565b60008281526033602052604090206002015461069090610285610da9565b6106ac5760405162461bcd60e51b81526004016104849061164b565b6106b68282610dad565b5050565b6106c2610da9565b6001600160a01b0316816001600160a01b0316146106f25760405162461bcd60e51b8152600401610484906119c2565b6106b68282610e16565b6067818154811061070957fe5b6000918252602090912001546001600160a01b0316905081565b600054610100900460ff168061073c575061073c610e7f565b8061074a575060005460ff16155b6107665760405162461bcd60e51b815260040161048490611876565b600054610100900460ff16158015610791576000805460ff1961ff0019909116610100171660011790555b610799610e90565b6107a46000336106ac565b6107bc600080516020611ab4833981519152336106ac565b606580546001600160a01b038086166001600160a01b031992831617909255606680549285169290911691909117905580156107fe576000805461ff00191690555b505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6065546001600160a01b031681565b6066546001600160a01b031681565b6065546000906001600160a01b031633146108715760405162461bcd60e51b81526004016104849061198b565b6066546001600160a01b0385811691161461089e5760405162461bcd60e51b81526004016104849061169a565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016108ce9190611552565b6040516020818303038152906040528051906020012085146109025760405162461bcd60e51b815260040161048490611833565b600061090e8484610f23565b9050600881600c81111561091e57fe5b1461093b5760405162461bcd60e51b81526004016104849061174f565b610943611222565b61094d8585610f64565b6020810151606854919250151560ff9091161515141561097f5760405162461bcd60e51b81526004016104849061193c565b60208101516068805460ff19168215151790556040517fce4347a8c71d04a62f940154f3607d6a42f153b91cb09d9ec71356d2b36beb32916109c091611582565b60405180910390a15060019695505050505050565b60008281526033602052604081206109ed9083610fac565b90505b92915050565b60008281526033602052604081206109ed9083610fb8565b600081565b610a2b600080516020611ab4833981519152336109f6565b610a475760405162461bcd60e51b815260040161048490611718565b60685460ff16610a695760405162461bcd60e51b8152600401610484906118c4565b6067548114610a8a5760405162461bcd60e51b815260040161048490611905565b60005b81811015610b3b5760678181548110610aa257fe5b6000918252602090912001546001600160a01b031663cb703bff8686868686818110610aca57fe5b9050602002016020810190610adf91906112aa565b6040518463ffffffff1660e01b8152600401610afd939291906115aa565b600060405180830381600087803b158015610b1757600080fd5b505af1158015610b2b573d6000803e3d6000fd5b505060019092019150610a8d9050565b5060655460405163f2f6360560e01b81526001600160a01b039091169063f2f6360590610b6e9087908790600401611596565b600060405180830381600087803b158015610b8857600080fd5b505af1158015610b9c573d6000803e3d6000fd5b5050505050505050565b610bbe600080516020611ab4833981519152336109f6565b610bda5760405162461bcd60e51b815260040161048490611718565b6067546000905b80821015610c2b57826001600160a01b031660678381548110610c0057fe5b6000918252602090912001546001600160a01b03161415610c2057610c2b565b600190910190610be1565b808210156107fe57610c3e816001610fcd565b821015610cb1576067610c52826001610fcd565b81548110610c5c57fe5b600091825260209091200154606780546001600160a01b039092169184908110610c8257fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6067805480610cbc57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b60008181526033602052604081206109f090610ff5565b600082815260336020526040902060020154610d1890610285610da9565b6106f25760405162461bcd60e51b8152600401610484906117e3565b60675460009081905b80821015610d8d57836001600160a01b031660678381548110610d5c57fe5b6000918252602090912001546001600160a01b03161415610d825760019250505061059e565b600190910190610d3d565b5060009392505050565b600080516020611ab483398151915281565b3390565b6000828152603360205260409020610dc59082611000565b156106b657610dd2610da9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020610e2e9082611015565b156106b657610e3b610da9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6000610e8a3061102a565b15905090565b600054610100900460ff1680610ea95750610ea9610e7f565b80610eb7575060005460ff16155b610ed35760405162461bcd60e51b815260040161048490611876565b600054610100900460ff16158015610efe576000805460ff1961ff0019909116610100171660011790555b610f06611030565b610f0e611030565b8015610f20576000805461ff00191690555b50565b600080610f32838501856112e9565b905060208106610f5857610f50610f4b84838188611a38565b610f23565b9150506109f0565b610f50838501856113d8565b610f6c611222565b6008610f788484610f23565b600c811115610f8357fe5b14610fa05760405162461bcd60e51b8152600401610484906116cf565b6109ed828401846114c6565b60006109ed83836110b1565b60006109ed836001600160a01b0384166110f6565b600082821115610fef5760405162461bcd60e51b8152600401610484906117ac565b50900390565b60006109f08261110e565b60006109ed836001600160a01b038416611112565b60006109ed836001600160a01b03841661115c565b3b151590565b600054610100900460ff16806110495750611049610e7f565b80611057575060005460ff16155b6110735760405162461bcd60e51b815260040161048490611876565b600054610100900460ff16158015610f0e576000805460ff1961ff0019909116610100171660011790558015610f20576000805461ff001916905550565b815460009082106110d45760405162461bcd60e51b815260040161048490611609565b8260000182815481106110e357fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b600061111e83836110f6565b611154575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109f0565b5060006109f0565b60008181526001830160205260408120548015611218578354600019808301919081019060009087908390811061118f57fe5b90600052602060002001549050808760000184815481106111ac57fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806111dc57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506109f0565b60009150506109f0565b6040518060400160405280611235611242565b8152600060209091015290565b60408051602081019091526000815290565b60008083601f840112611265578182fd5b50813567ffffffffffffffff81111561127c578182fd5b60208301915083602082850101111561129457600080fd5b9250929050565b8035600d81106109f057600080fd5b6000602082840312156112bb578081fd5b81356112c681611a90565b9392505050565b6000602082840312156112de578081fd5b81516112c681611aa5565b6000602082840312156112fa578081fd5b5035919050565b60008060408385031215611313578081fd5b82359150602083013561132581611a90565b809150509250929050565b60008060008060608587031215611345578182fd5b84359350602085013561135781611a90565b9250604085013567ffffffffffffffff811115611372578283fd5b61137e87828801611254565b95989497509550505050565b6000806040838503121561139c578182fd5b50508035926020909101359150565b600080604083850312156113bd578182fd5b82356113c881611a90565b9150602083013561132581611a90565b6000602082840312156113e9578081fd5b6109ed838361129b565b60008060208385031215611405578182fd5b823567ffffffffffffffff81111561141b578283fd5b61142785828601611254565b90969095509350505050565b60008060008060408587031215611448578384fd5b843567ffffffffffffffff8082111561145f578586fd5b61146b88838901611254565b90965094506020870135915080821115611483578384fd5b818701915087601f830112611496578384fd5b8135818111156114a4578485fd5b88602080830285010111156114b7578485fd5b95989497505060200194505050565b600081830360408112156114d8578182fd5b6114e26040611a11565b60208212156114ef578283fd5b6114f96020611a11565b9150611505858561129b565b825290815260208301359061151982611aa5565b60208101919091529392505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008251611564818460208701611a60565b9190910192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b90815260200190565b60006020825261043f602083018486611528565b6000604082526115be604083018587611528565b905060018060a01b0383166020830152949350505050565b60006020825282518060208401526115f5816040850160208701611a60565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252818101527f53656e6465722066726f6d204d61696e6e657420697320696e636f7272656374604082015260600190565b60208082526029908201527f4d6573736167652074797065206973206e6f7420496e746572636861696e206360408201526837b73732b1ba34b7b760b91b606082015260800190565b6020808252601a908201527f5245474953545241525f524f4c45206973207265717569726564000000000000604082015260600190565b60208082526038908201527f546865206d6573736167652073686f756c6420636f6e7461696e206120696e7460408201527f6572636861696e20636f6e6e656374696f6e2073746174650000000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526023908201527f536f7572636520636861696e206e616d652073686f756c64206265204d61696e6040820152621b995d60ea1b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f496e746572636861696e20636f6e6e656374696f6e206e6f7420616c6c6f77656040820152601960fa1b606082015260800190565b6020808252601d908201527f496e636f7272656374206e756d626572206f6620616464726573736573000000604082015260600190565b6020808252602f908201527f496e746572636861696e20636f6e6e656374696f6e2073746174652073686f7560408201526e1b1908189948191a5999995c995b9d608a1b606082015260800190565b6020808252601d908201527f53656e646572206973206e6f742061206d6573736167652070726f7879000000604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60405181810167ffffffffffffffff81118282101715611a3057600080fd5b604052919050565b60008085851115611a47578182fd5b83861115611a53578182fd5b5050820193919092039150565b60005b83811015611a7b578181015183820152602001611a63565b83811115611a8a576000848401525b50505050565b6001600160a01b0381168114610f2057600080fd5b8015158114610f2057600080fdfeedcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c309238a2646970667358221220b5eb8c3b77cbd30cbf8084a2c674c7f133c5691aa16514e744eed381a945dd0864736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/build/lib/ima_predeployed/contract_generator.py b/predeployed/build/lib/ima_predeployed/contract_generator.py new file mode 100644 index 000000000..217a702fa --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contract_generator.py @@ -0,0 +1,99 @@ +import json +import os +from web3 import Web3 + + +def to_even_length(hex_string: str) -> str: + assert hex_string.startswith('0x') + if len(hex_string) % 2 != 0: + return "0x0" + hex_string[2:] + else: + return hex_string + + +def add_0x(bytes_string: str) -> str: + if bytes_string.startswith('0x'): + return bytes_string + else: + return '0x' + bytes_string + + +def calculate_mapping_value_slot(slot: int, key: any, key_type: str) -> int: + return int.from_bytes(Web3.solidityKeccak([key_type, 'uint256'], [key, slot]), 'big') + + +def calculate_array_value_slot(slot: int, index: int) -> int: + return int.from_bytes(Web3.solidityKeccak(['uint256'], [slot]), 'big') + index + + +def next_slot(previous_slot: int) -> int: + return previous_slot + 1 + + +class ContractGenerator: + def __init__(self, artifact_filename: str): + artifacts_dir = os.path.join(os.path.dirname(__file__), 'artifacts') + artifacts_path = os.path.join(artifacts_dir, artifact_filename) + with open(artifacts_path, encoding='utf-8') as fp: + contract = json.load(fp) + self.bytecode = contract['deployedBytecode'] + self.storage = {} + + def generate_contract(self, balance: int = 0, nonce: int = 0) -> dict: + assert isinstance(self.bytecode, str) + assert isinstance(self.storage, dict) + contract = { + 'code': self.bytecode, + 'balance': str(balance) + } + if self.storage: + contract['storage'] = self.storage + if nonce > 0: + contract['nonce'] = nonce + return contract + + # private + + def _write_address(self, slot: int, address: str) -> None: + self.storage[to_even_length(hex(slot))] = address.lower() + + def _write_bytes32(self, slot: int, data: bytes) -> None: + assert len(data) <= 32 + self.storage[to_even_length(hex(slot))] = to_even_length(add_0x(data.hex())) + + def _write_uint256(self, slot: int, value: int) -> None: + self.storage[to_even_length(hex(slot))] = to_even_length(add_0x(hex(value))) + + def _setup_role(self, slot: int, role: bytes, accounts: [str]): + role_data_slot = calculate_mapping_value_slot(slot, role, 'bytes32') + members_slot = role_data_slot + values_slot = members_slot + indexes_slot = members_slot + 1 + self._write_uint256(values_slot, len(accounts)) + for i, account in enumerate(accounts): + self._write_address(calculate_array_value_slot(values_slot, i), account) + self._write_uint256(calculate_mapping_value_slot(indexes_slot, int(account, 16), 'uint256'), i + 1) + + def _write_addresses_array(self, slot: int, values: list) -> None: + self._write_uint256(slot, len(values)) + for i, address in enumerate(values): + address_slot = calculate_array_value_slot(slot, i) + self._write_address(address_slot, address) + + def _write_string(self, slot: int, value: str) -> None: + binary = value.encode() + length = len(binary) + if length < 32: + binary += (2 * length).to_bytes(32 - length, 'big') + self._write_bytes32(slot, binary) + else: + self._write_uint256(slot, 2 * length + 1) + + def chunks(size, source): + for i in range(0, len(source), size): + yield source[i:i + size] + + for index, data in enumerate(chunks(32, binary)): + if len(data) < 32: + data += int(0).to_bytes(32 - len(data), 'big') + self._write_bytes32(calculate_array_value_slot(slot, index), data) diff --git a/proxy/predeployed/src/ima_predeployed/contracts/__init__.py b/predeployed/build/lib/ima_predeployed/contracts/__init__.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/__init__.py rename to predeployed/build/lib/ima_predeployed/contracts/__init__.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/admin_upgradeability_proxy.py b/predeployed/build/lib/ima_predeployed/contracts/admin_upgradeability_proxy.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/admin_upgradeability_proxy.py rename to predeployed/build/lib/ima_predeployed/contracts/admin_upgradeability_proxy.py diff --git a/predeployed/build/lib/ima_predeployed/contracts/community_locker.py b/predeployed/build/lib/ima_predeployed/contracts/community_locker.py new file mode 100644 index 000000000..67f9d290f --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/community_locker.py @@ -0,0 +1,50 @@ +from ima_predeployed.addresses import MESSAGE_PROXY_FOR_SCHAIN_ADDRESS, TOKEN_MANAGER_LINKER_ADDRESS +from ima_predeployed.contract_generator import ContractGenerator, next_slot +from tools import w3 + + +class CommunityLockerGenerator(ContractGenerator): + ARTIFACT_FILENAME = "CommunityLocker.json" + DEFAULT_ADMIN_ROLE = (0).to_bytes(32, 'big') + DEFAULT_TIME_LIMIT_SEC = 5 * 60 + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # -------CommunityLocker------- + # 101: messageProxy + # 102: tokenManagerLinker + # 103: schainHash + # 104: timeLimitPerMessage + # 105: _unfrozenUsers + # 106: _lastMessageTimeStamp + + INITIALIZED_SLOT = 0 + ROLES_SLOT = 51 + MESSAGE_PROXY_SLOT = 101 + TOKEN_MANAGER_LINKER_SLOT = next_slot(MESSAGE_PROXY_SLOT) + SCHAIN_HASH_SLOT = next_slot(TOKEN_MANAGER_LINKER_SLOT) + TIME_LIMIT_PER_MESSAGE_SLOT = next_slot(SCHAIN_HASH_SLOT) + + def __init__(self, deployer_address: str, schain_name: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup(deployer_address, schain_name) + + # private + + def _setup(self, deployer_address: str, schain_name: str) -> None: + self._write_uint256(self.INITIALIZED_SLOT, 1) + self._setup_role(self.ROLES_SLOT, self.DEFAULT_ADMIN_ROLE, [deployer_address]) + self._write_address(self.MESSAGE_PROXY_SLOT, MESSAGE_PROXY_FOR_SCHAIN_ADDRESS) + self._write_address(self.TOKEN_MANAGER_LINKER_SLOT, TOKEN_MANAGER_LINKER_ADDRESS) + self._write_bytes32(self.SCHAIN_HASH_SLOT, w3.solidityKeccak(['string'], [schain_name])) + self._write_uint256(self.TIME_LIMIT_PER_MESSAGE_SLOT, self.DEFAULT_TIME_LIMIT_SEC) diff --git a/predeployed/build/lib/ima_predeployed/contracts/eth_erc20.py b/predeployed/build/lib/ima_predeployed/contracts/eth_erc20.py new file mode 100644 index 000000000..fd2be93e5 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/eth_erc20.py @@ -0,0 +1,62 @@ +from ima_predeployed.addresses import TOKEN_MANAGER_ETH_ADDRESS +from ima_predeployed.contract_generator import ContractGenerator, next_slot +from tools import w3 + + +class EthErc20Generator(ContractGenerator): + ARTIFACT_FILENAME = "EthErc20.json" + DEFAULT_ADMIN_ROLE = (0).to_bytes(32, 'big') + MINTER_ROLE = w3.solidityKeccak(['string'], ['MINTER_ROLE']) + BURNER_ROLE = w3.solidityKeccak(['string'], ['BURNER_ROLE']) + NAME = 'ERC20 Ether Clone' + SYMBOL = 'ETHC' + DECIMALS = 18 + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # -------ERC20Upgradeable------- + # 101: _balances + # 102: _allowances + # 103: _totalSupply + # 104: _name + # 105: _symbol + # 106: _decimals + # 107: __gap + # ... __gap + # 150: __gap + # ---ERC20BurnableUpgradeable--- + # 151: __gap + # ... __gap + # 200: __gap + # -----------EthErc20----------- + + INITIALIZED_SLOT = 0 + ROLES_SLOT = 51 + NAME_SLOT = 104 + SYMBOL_SLOT = next_slot(NAME_SLOT) + DECIMALS_SLOT = next_slot(SYMBOL_SLOT) + + def __init__(self, deployer_address: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup(deployer_address) + + # private + + def _setup(self, deployer_address: str) -> None: + self._write_uint256(self.INITIALIZED_SLOT, 1) + self._setup_role(self.ROLES_SLOT, self.DEFAULT_ADMIN_ROLE, [deployer_address]) + self._setup_role(self.ROLES_SLOT, self.MINTER_ROLE, [TOKEN_MANAGER_ETH_ADDRESS]) + self._setup_role(self.ROLES_SLOT, self.BURNER_ROLE, [TOKEN_MANAGER_ETH_ADDRESS]) + self._write_string(self.NAME_SLOT, self.NAME) + self._write_string(self.SYMBOL_SLOT, self.SYMBOL) + self._write_uint256(self.DECIMALS_SLOT, self.DECIMALS) diff --git a/predeployed/build/lib/ima_predeployed/contracts/key_storage.py b/predeployed/build/lib/ima_predeployed/contracts/key_storage.py new file mode 100644 index 000000000..515b41a9d --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/key_storage.py @@ -0,0 +1,33 @@ +from ..contract_generator import ContractGenerator + + +class KeyStorageGenerator(ContractGenerator): + ARTIFACT_FILENAME = "KeyStorage.json" + DEFAULT_ADMIN_ROLE = (0).to_bytes(32, 'big') + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ----------KeyStorage---------- + + INITIALIZED_SLOT = 0 + ROLES_SLOT = 51 + + def __init__(self, deployer_address: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup(deployer_address) + + # private + + def _setup(self, deployer_address: str) -> None: + self._write_uint256(self.INITIALIZED_SLOT, 1) + self._setup_role(self.ROLES_SLOT, self.DEFAULT_ADMIN_ROLE, [deployer_address]) diff --git a/predeployed/build/lib/ima_predeployed/contracts/message_proxy_for_schain.py b/predeployed/build/lib/ima_predeployed/contracts/message_proxy_for_schain.py new file mode 100644 index 000000000..f0ac4fd50 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/message_proxy_for_schain.py @@ -0,0 +1,49 @@ +from ..contract_generator import ContractGenerator, calculate_mapping_value_slot, calculate_array_value_slot +from ..addresses import KEY_STORAGE_ADDRESS +from web3 import Web3 + + +class MessageProxyForSchainGenerator(ContractGenerator): + ARTIFACT_FILENAME = "MessageProxyForSchain.json" + DEFAULT_ADMIN_ROLE = (0).to_bytes(32, 'big') + MAINNET_HASH = Web3.solidityKeccak(['string'], ['Mainnet']) + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ----MessageProxyForSchain---- + # 101: keyStorage + # 102: connectedChains + # 103: _outgoingMessageDataHash + # 104: _idxHead + # 105: _idxTail + + INITIALIZED_SLOT = 0 + ROLES_SLOT = 51 + KEY_STORAGE_SLOT = 101 + CONNECTED_CHAINS_SLOT = 102 + + def __init__(self, deployer_address: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup(deployer_address) + + # private + + def _setup(self, deployer_address: str) -> None: + self._write_uint256(self.INITIALIZED_SLOT, 1) + self._setup_role(self.ROLES_SLOT, self.DEFAULT_ADMIN_ROLE, [deployer_address]) + self._write_address(self.KEY_STORAGE_SLOT, KEY_STORAGE_ADDRESS) + + connected_chain_info_slot = calculate_mapping_value_slot( + self.CONNECTED_CHAINS_SLOT, self.MAINNET_HASH, 'bytes32') + inited_slot = connected_chain_info_slot + 2 + self._write_uint256(inited_slot, 1) diff --git a/proxy/predeployed/src/ima_predeployed/contracts/proxy_admin.py b/predeployed/build/lib/ima_predeployed/contracts/proxy_admin.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/proxy_admin.py rename to predeployed/build/lib/ima_predeployed/contracts/proxy_admin.py diff --git a/predeployed/build/lib/ima_predeployed/contracts/token_manager.py b/predeployed/build/lib/ima_predeployed/contracts/token_manager.py new file mode 100644 index 000000000..263126a06 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/token_manager.py @@ -0,0 +1,58 @@ +from ima_predeployed.addresses import MESSAGE_PROXY_FOR_SCHAIN_ADDRESS, TOKEN_MANAGER_LINKER_ADDRESS, \ + COMMUNITY_LOCKER_ADDRESS +from ima_predeployed.contract_generator import ContractGenerator, next_slot +from tools import w3 + + +class TokenManagerGenerator(ContractGenerator): + ARTIFACT_FILENAME = "TokenManager.json" + DEFAULT_ADMIN_ROLE = (0).to_bytes(32, 'big') + AUTOMATIC_DEPLOY_ROLE = w3.solidityKeccak(['string'], ['AUTOMATIC_DEPLOY_ROLE']) + TOKEN_REGISTRAR_ROLE = w3.solidityKeccak(['string'], ['TOKEN_REGISTRAR_ROLE']) + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ---------TokenManager--------- + # 101: messageProxy + # 102: tokenManagerLinker + # 103: communityLocker + # 104: schainHash + # 105: depositBox, automaticDeploy + # 106: tokenManagers + + INITIALIZED_SLOT = 0 + ROLES_SLOT = 51 + MESSAGE_PROXY_SLOT = 101 + TOKEN_MANAGER_LINKER_SLOT = next_slot(MESSAGE_PROXY_SLOT) + COMMUNITY_LOCKER_SLOT = next_slot(TOKEN_MANAGER_LINKER_SLOT) + SCHAIN_HASH_SLOT = next_slot(COMMUNITY_LOCKER_SLOT) + DEPOSIT_BOX_SLOT = next_slot(SCHAIN_HASH_SLOT) + AUTOMATIC_DEPLOY_SLOT = DEPOSIT_BOX_SLOT + TOKEN_MANAGERS_SLOT = next_slot(AUTOMATIC_DEPLOY_SLOT) + + def __init__(self, deployer_address: str, deposit_box_address: str, schain_name: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup_token_manager(deployer_address, deposit_box_address, schain_name) + + # private + + def _setup_token_manager(self, deployer_address: str, deposit_box_address: str, schain_name: str) -> None: + self._write_uint256(self.INITIALIZED_SLOT, 1) + self._setup_role(self.ROLES_SLOT, self.DEFAULT_ADMIN_ROLE, [deployer_address]) + self._setup_role(self.ROLES_SLOT, self.AUTOMATIC_DEPLOY_ROLE, [deployer_address]) + self._setup_role(self.ROLES_SLOT, self.TOKEN_REGISTRAR_ROLE, [deployer_address]) + self._write_address(self.MESSAGE_PROXY_SLOT, MESSAGE_PROXY_FOR_SCHAIN_ADDRESS) + self._write_address(self.TOKEN_MANAGER_LINKER_SLOT, TOKEN_MANAGER_LINKER_ADDRESS) + self._write_address(self.COMMUNITY_LOCKER_SLOT, COMMUNITY_LOCKER_ADDRESS) + self._write_bytes32(self.SCHAIN_HASH_SLOT, w3.solidityKeccak(['string'], [schain_name])) + self._write_address(self.DEPOSIT_BOX_SLOT, deposit_box_address) diff --git a/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc20.py b/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc20.py new file mode 100644 index 000000000..7a7eb9dcf --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc20.py @@ -0,0 +1,31 @@ +from ima_predeployed.contracts.token_manager import TokenManagerGenerator + + +class TokenManagerErc20Generator(TokenManagerGenerator): + ARTIFACT_FILENAME = "TokenManagerERC20.json" + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ---------TokenManager--------- + # 101: messageProxy + # 102: tokenManagerLinker + # 103: communityLocker + # 104: schainHash + # 105: depositBox, automaticDeploy + # 106: tokenManagers + # ------TokenManagerERC20------ + # 107: clonesErc20 + # 108: totalSupplyOnMainnet + + def __init__(self, deployer_address: str, deposit_box_address: str, schain_name: str): + super().__init__(deployer_address, deposit_box_address, schain_name) diff --git a/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc721.py b/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc721.py new file mode 100644 index 000000000..08de46f58 --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc721.py @@ -0,0 +1,30 @@ +from ima_predeployed.contracts.token_manager import TokenManagerGenerator + + +class TokenManagerErc721Generator(TokenManagerGenerator): + ARTIFACT_FILENAME = "TokenManagerERC721.json" + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ---------TokenManager--------- + # 101: messageProxy + # 102: tokenManagerLinker + # 103: communityLocker + # 104: schainHash + # 105: depositBox, automaticDeploy + # 106: tokenManagers + # ------TokenManagerERC721------ + # 107: clonesErc721 + + def __init__(self, deployer_address: str, deposit_box_address: str, schain_name: str): + super().__init__(deployer_address, deposit_box_address, schain_name) diff --git a/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc_20.py b/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc_20.py new file mode 100644 index 000000000..d6aa419dc --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/token_manager_erc_20.py @@ -0,0 +1,35 @@ +from ima_predeployed.addresses import MESSAGE_PROXY_FOR_SCHAIN_ADDRESS, TOKEN_MANAGER_LINKER_ADDRESS, \ + COMMUNITY_LOCKER_ADDRESS, ETH_ERC_20_ADDRESS +from ima_predeployed.contract_generator import next_slot +from ima_predeployed.contracts.token_manager import TokenManagerGenerator +from tools import w3 + + +class TokenManagerErc20Generator(TokenManagerGenerator): + ARTIFACT_FILENAME = "TokenManagerERC20.json" + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ---------TokenManager--------- + # 101: messageProxy + # 102: tokenManagerLinker + # 103: communityLocker + # 104: schainHash + # 105: depositBox, automaticDeploy + # 106: tokenManagers + # ------TokenManagerERC20------ + # 107: clonesErc20 + # 108: totalSupplyOnMainnet + + def __init__(self, deployer_address: str, deposit_box_address: str, schain_name: str): + super().__init__(deployer_address, deposit_box_address, schain_name) diff --git a/predeployed/build/lib/ima_predeployed/contracts/token_manager_eth.py b/predeployed/build/lib/ima_predeployed/contracts/token_manager_eth.py new file mode 100644 index 000000000..22e85615c --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/token_manager_eth.py @@ -0,0 +1,40 @@ +from ima_predeployed.addresses import ETH_ERC20_ADDRESS +from ima_predeployed.contract_generator import next_slot +from ima_predeployed.contracts.token_manager import TokenManagerGenerator + + +class TokenManagerEthGenerator(TokenManagerGenerator): + ARTIFACT_FILENAME = "TokenManagerEth.json" + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ---------TokenManager--------- + # 101: messageProxy + # 102: tokenManagerLinker + # 103: communityLocker + # 104: schainHash + # 105: depositBox, automaticDeploy + # 106: tokenManagers + # -------TokenManagerEth------- + # 107: ethErc20 + + ETH_ERC_20_SLOT = next_slot(TokenManagerGenerator.TOKEN_MANAGERS_SLOT) + + def __init__(self, deployer_address: str, deposit_box_address: str, schain_name: str): + super().__init__(deployer_address, deposit_box_address, schain_name) + self._setup() + + # private + + def _setup(self) -> None: + self._write_address(self.ETH_ERC_20_SLOT, ETH_ERC20_ADDRESS) diff --git a/predeployed/build/lib/ima_predeployed/contracts/token_manager_linker.py b/predeployed/build/lib/ima_predeployed/contracts/token_manager_linker.py new file mode 100644 index 000000000..8ae02375f --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/contracts/token_manager_linker.py @@ -0,0 +1,50 @@ +from ima_predeployed.addresses import MESSAGE_PROXY_FOR_SCHAIN_ADDRESS, TOKEN_MANAGER_ERC20_ADDRESS, \ + TOKEN_MANAGER_ERC721_ADDRESS, TOKEN_MANAGER_ETH_ADDRESS +from tools import w3 +from ..contract_generator import ContractGenerator, next_slot + + +class TokenManagerLinkerGenerator(ContractGenerator): + ARTIFACT_FILENAME = "TokenManagerLinker.json" + DEFAULT_ADMIN_ROLE = (0).to_bytes(32, 'big') + REGISTRAR_ROLE = w3.solidityKeccak(['string'], ['REGISTRAR_ROLE']) + + # ---------- storage ---------- + # --------Initializable-------- + # 0: _initialized, _initializing; + # -----ContextUpgradeable------ + # 1: __gap + # ... __gap + # 50: __gap + # --AccessControlUpgradeable--- + # 51: _roles + # 52: __gap + # ... __gap + # 100: __gap + # ------TokenManagerLinker------ + # 101: messageProxy + # 102: linkerAddress + # 103: tokenManagers + # 104: interchainConnections + + INITIALIZED_SLOT = 0 + ROLES_SLOT = 51 + MESSAGE_PROXY_SLOT = 101 + LINKER_ADDRESS_SLOT = next_slot(MESSAGE_PROXY_SLOT) + TOKEN_MANAGERS_SLOT = next_slot(LINKER_ADDRESS_SLOT) + + def __init__(self, deployer_address: str, linker_address: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup(deployer_address, linker_address) + + # private + + def _setup(self, deployer_address: str, linker_addres: str) -> None: + self._write_uint256(self.INITIALIZED_SLOT, 1) + self._setup_role(self.ROLES_SLOT, self.DEFAULT_ADMIN_ROLE, [deployer_address]) + self._setup_role(self.ROLES_SLOT, self.REGISTRAR_ROLE, [deployer_address]) + self._write_address(self.MESSAGE_PROXY_SLOT, MESSAGE_PROXY_FOR_SCHAIN_ADDRESS) + self._write_address(self.LINKER_ADDRESS_SLOT, linker_addres) + self._write_addresses_array( + self.TOKEN_MANAGERS_SLOT, + [TOKEN_MANAGER_ETH_ADDRESS, TOKEN_MANAGER_ERC20_ADDRESS, TOKEN_MANAGER_ERC721_ADDRESS]) diff --git a/predeployed/build/lib/ima_predeployed/generator.py b/predeployed/build/lib/ima_predeployed/generator.py new file mode 100644 index 000000000..41e66e3be --- /dev/null +++ b/predeployed/build/lib/ima_predeployed/generator.py @@ -0,0 +1,124 @@ +import json +import os + +from ima_predeployed.contracts.eth_erc20 import EthErc20Generator +from ima_predeployed.contracts.token_manager_erc20 import TokenManagerErc20Generator +from ima_predeployed.contracts.token_manager_erc721 import TokenManagerErc721Generator +from ima_predeployed.contracts.token_manager_eth import TokenManagerEthGenerator +from ima_predeployed.contracts.token_manager_linker import TokenManagerLinkerGenerator +from .contracts.community_locker import CommunityLockerGenerator +from .contract_generator import ContractGenerator +from .contracts.key_storage import KeyStorageGenerator +from .upgradeable_contract_generator import UpgradeableContractGenerator +from .contracts.proxy_admin import ProxyAdminGenerator +from .contracts.message_proxy_for_schain import MessageProxyForSchainGenerator +from .addresses import \ + PROXY_ADMIN_ADDRESS, \ + MESSAGE_PROXY_FOR_SCHAIN_ADDRESS, \ + MESSAGE_PROXY_FOR_SCHAIN_IMPLEMENTATION_ADDRESS, KEY_STORAGE_IMPLEMENTATION_ADDRESS, KEY_STORAGE_ADDRESS, \ + COMMUNITY_LOCKER_IMPLEMENTATION_ADDRESS, COMMUNITY_LOCKER_ADDRESS, TOKEN_MANAGER_LINKER_IMPLEMENTATION_ADDRESS, \ + TOKEN_MANAGER_LINKER_ADDRESS, TOKEN_MANAGER_ETH_IMPLEMENTATION_ADDRESS, TOKEN_MANAGER_ETH_ADDRESS, \ + TOKEN_MANAGER_ERC20_IMPLEMENTATION_ADDRESS, TOKEN_MANAGER_ERC20_ADDRESS, \ + TOKEN_MANAGER_ERC721_IMPLEMENTATION_ADDRESS, TOKEN_MANAGER_ERC721_ADDRESS, ETH_ERC20_IMPLEMENTATION_ADDRESS, \ + ETH_ERC20_ADDRESS + + +def generate_contracts( + owner_address: str, + schain_name: str, + contracts_on_mainnet: dict) -> dict: + proxy_admin = ProxyAdminGenerator(owner_address) + + message_proxy_for_schain_implementation = ContractGenerator(MessageProxyForSchainGenerator.ARTIFACT_FILENAME) + message_proxy_for_schain = UpgradeableContractGenerator( + MESSAGE_PROXY_FOR_SCHAIN_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + MessageProxyForSchainGenerator(owner_address)) + + key_storage_implementation = ContractGenerator(KeyStorageGenerator.ARTIFACT_FILENAME) + key_storage = UpgradeableContractGenerator( + KEY_STORAGE_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + KeyStorageGenerator(owner_address)) + + community_locker_implementation = ContractGenerator(CommunityLockerGenerator.ARTIFACT_FILENAME) + community_locker = UpgradeableContractGenerator( + COMMUNITY_LOCKER_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + CommunityLockerGenerator(owner_address, schain_name) + ) + + token_manager_linker_implementation = ContractGenerator(TokenManagerLinkerGenerator.ARTIFACT_FILENAME) + token_manager_linker = UpgradeableContractGenerator( + TOKEN_MANAGER_LINKER_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + TokenManagerLinkerGenerator(owner_address, contracts_on_mainnet['linker']) + ) + + token_manager_eth_implementation = ContractGenerator(TokenManagerEthGenerator.ARTIFACT_FILENAME) + token_manager_eth = UpgradeableContractGenerator( + TOKEN_MANAGER_ETH_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + TokenManagerEthGenerator(owner_address, contracts_on_mainnet['eth_deposit_box'], schain_name) + ) + + token_manager_erc20_implementation = ContractGenerator(TokenManagerErc20Generator.ARTIFACT_FILENAME) + token_manager_erc20 = UpgradeableContractGenerator( + TOKEN_MANAGER_ERC20_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + TokenManagerErc20Generator(owner_address, contracts_on_mainnet['erc20_deposit_box'], schain_name) + ) + + token_manager_erc721_implementation = ContractGenerator(TokenManagerErc721Generator.ARTIFACT_FILENAME) + token_manager_erc721 = UpgradeableContractGenerator( + TOKEN_MANAGER_ERC721_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + TokenManagerErc721Generator(owner_address, contracts_on_mainnet['erc721_deposit_box'], schain_name) + ) + + eth_erc20_implementation = ContractGenerator(EthErc20Generator.ARTIFACT_FILENAME) + eth_erc20 = UpgradeableContractGenerator( + ETH_ERC20_IMPLEMENTATION_ADDRESS, + PROXY_ADMIN_ADDRESS, + EthErc20Generator(owner_address) + ) + + return { + PROXY_ADMIN_ADDRESS: proxy_admin.generate_contract(), + + MESSAGE_PROXY_FOR_SCHAIN_ADDRESS: message_proxy_for_schain.generate_contract(), + MESSAGE_PROXY_FOR_SCHAIN_IMPLEMENTATION_ADDRESS: message_proxy_for_schain_implementation.generate_contract(), + + KEY_STORAGE_ADDRESS: key_storage.generate_contract(), + KEY_STORAGE_IMPLEMENTATION_ADDRESS: key_storage_implementation.generate_contract(), + + COMMUNITY_LOCKER_ADDRESS: community_locker.generate_contract(), + COMMUNITY_LOCKER_IMPLEMENTATION_ADDRESS: community_locker_implementation.generate_contract(), + + TOKEN_MANAGER_LINKER_ADDRESS: token_manager_linker.generate_contract(), + TOKEN_MANAGER_LINKER_IMPLEMENTATION_ADDRESS: token_manager_linker_implementation.generate_contract(), + + TOKEN_MANAGER_ETH_ADDRESS: token_manager_eth.generate_contract(), + TOKEN_MANAGER_ETH_IMPLEMENTATION_ADDRESS: token_manager_eth_implementation.generate_contract(), + + TOKEN_MANAGER_ERC20_ADDRESS: token_manager_erc20.generate_contract(), + TOKEN_MANAGER_ERC20_IMPLEMENTATION_ADDRESS: token_manager_erc20_implementation.generate_contract(), + + TOKEN_MANAGER_ERC721_ADDRESS: token_manager_erc721.generate_contract(), + TOKEN_MANAGER_ERC721_IMPLEMENTATION_ADDRESS: token_manager_erc721_implementation.generate_contract(), + + ETH_ERC20_ADDRESS: eth_erc20.generate_contract(), + ETH_ERC20_IMPLEMENTATION_ADDRESS: eth_erc20_implementation.generate_contract() + } + + +def main() -> None: + contracts_dir = os.path.join(os.path.dirname(__file__), 'artifacts') + proxy_admin_path = os.path.join(contracts_dir, 'ProxyAdmin.json') + with open(proxy_admin_path, encoding='utf-8') as fp: + proxy_admin = json.load(fp) + print(proxy_admin['contractName']) + + +if __name__ == '__main__': + main() diff --git a/proxy/predeployed/src/ima_predeployed/upgradeable_contract_generator.py b/predeployed/build/lib/ima_predeployed/upgradeable_contract_generator.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/upgradeable_contract_generator.py rename to predeployed/build/lib/ima_predeployed/upgradeable_contract_generator.py diff --git a/predeployed/dist/ima-predeployed-0.0.1.tar.gz b/predeployed/dist/ima-predeployed-0.0.1.tar.gz new file mode 100644 index 000000000..688a66237 Binary files /dev/null and b/predeployed/dist/ima-predeployed-0.0.1.tar.gz differ diff --git a/predeployed/dist/ima-predeployed-1.3.4a12.tar.gz b/predeployed/dist/ima-predeployed-1.3.4a12.tar.gz new file mode 100644 index 000000000..1b4665a5a Binary files /dev/null and b/predeployed/dist/ima-predeployed-1.3.4a12.tar.gz differ diff --git a/predeployed/dist/ima_predeployed-0.0.1-py3-none-any.whl b/predeployed/dist/ima_predeployed-0.0.1-py3-none-any.whl new file mode 100644 index 000000000..f0a7cd1c8 Binary files /dev/null and b/predeployed/dist/ima_predeployed-0.0.1-py3-none-any.whl differ diff --git a/predeployed/dist/ima_predeployed-1.3.4a12-py3-none-any.whl b/predeployed/dist/ima_predeployed-1.3.4a12-py3-none-any.whl new file mode 100644 index 000000000..c83f17191 Binary files /dev/null and b/predeployed/dist/ima_predeployed-1.3.4a12-py3-none-any.whl differ diff --git a/proxy/predeployed/pyproject.toml b/predeployed/pyproject.toml similarity index 100% rename from proxy/predeployed/pyproject.toml rename to predeployed/pyproject.toml diff --git a/proxy/predeployed/scripts/build_package.sh b/predeployed/scripts/build_package.sh similarity index 100% rename from proxy/predeployed/scripts/build_package.sh rename to predeployed/scripts/build_package.sh diff --git a/proxy/predeployed/scripts/generate_abi.py b/predeployed/scripts/generate_abi.py similarity index 100% rename from proxy/predeployed/scripts/generate_abi.py rename to predeployed/scripts/generate_abi.py diff --git a/proxy/predeployed/scripts/generate_package_version.py b/predeployed/scripts/generate_package_version.py similarity index 100% rename from proxy/predeployed/scripts/generate_package_version.py rename to predeployed/scripts/generate_package_version.py diff --git a/proxy/predeployed/scripts/prepare_artifacts.py b/predeployed/scripts/prepare_artifacts.py similarity index 100% rename from proxy/predeployed/scripts/prepare_artifacts.py rename to predeployed/scripts/prepare_artifacts.py diff --git a/proxy/predeployed/scripts/publish_package.sh b/predeployed/scripts/publish_package.sh similarity index 100% rename from proxy/predeployed/scripts/publish_package.sh rename to predeployed/scripts/publish_package.sh diff --git a/proxy/predeployed/setup.cfg b/predeployed/setup.cfg similarity index 100% rename from proxy/predeployed/setup.cfg rename to predeployed/setup.cfg diff --git a/proxy/predeployed/src/ima_predeployed/artifacts/.gitkeep b/predeployed/src/ima_predeployed/__init__.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/artifacts/.gitkeep rename to predeployed/src/ima_predeployed/__init__.py diff --git a/proxy/predeployed/src/ima_predeployed/addresses.py b/predeployed/src/ima_predeployed/addresses.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/addresses.py rename to predeployed/src/ima_predeployed/addresses.py diff --git a/predeployed/src/ima_predeployed/artifacts/.gitkeep b/predeployed/src/ima_predeployed/artifacts/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/predeployed/src/ima_predeployed/artifacts/AdminUpgradeabilityProxy.json b/predeployed/src/ima_predeployed/artifacts/AdminUpgradeabilityProxy.json new file mode 100644 index 000000000..cda26649a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/AdminUpgradeabilityProxy.json @@ -0,0 +1,142 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "AdminUpgradeabilityProxy", + "sourceName": "contracts/proxy/AdminUpgradeabilityProxy.sol", + "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": "", + "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": "", + "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" + } + ], + "bytecode": "0x60806040526040516108d23803806108d28339818101604052606081101561002657600080fd5b8151602083015160408085018051915193959294830192918464010000000082111561005157600080fd5b90830190602082018581111561006657600080fd5b825164010000000081118282018810171561008057600080fd5b82525081516020918201929091019080838360005b838110156100ad578181015183820152602001610095565b50505050905090810190601f1680156100da5780820380516001836020036101000a031916815260200191505b50604052508491508290506100ee826101bf565b8051156101a6576000826001600160a01b0316826040518082805190602001908083835b602083106101315780518252601f199092019160209182019101610112565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610191576040519150601f19603f3d011682016040523d82523d6000602084013e610196565b606091505b50509050806101a457600080fd5b505b506101ae9050565b6101b782610231565b50505061025b565b6101d28161025560201b6103b41760201c565b61020d5760405162461bcd60e51b815260040180806020018281038252603b815260200180610897603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b3b151590565b61062d8061026a6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100985780635c60da1b146101185780638f28397014610149578063f851a4401461017c5761005d565b3661005d5761005b610191565b005b61005b610191565b34801561007157600080fd5b5061005b6004803603602081101561008857600080fd5b50356001600160a01b03166101ab565b61005b600480360360408110156100ae57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100d957600080fd5b8201836020820111156100eb57600080fd5b8035906020019184600183028401116401000000008311171561010d57600080fd5b5090925090506101e5565b34801561012457600080fd5b5061012d610292565b604080516001600160a01b039092168252519081900360200190f35b34801561015557600080fd5b5061005b6004803603602081101561016c57600080fd5b50356001600160a01b03166102cf565b34801561018857600080fd5b5061012d610389565b6101996103ba565b6101a96101a461041a565b61043f565b565b6101b3610463565b6001600160a01b0316336001600160a01b031614156101da576101d581610488565b6101e2565b6101e2610191565b50565b6101ed610463565b6001600160a01b0316336001600160a01b031614156102855761020f83610488565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d806000811461026c576040519150601f19603f3d011682016040523d82523d6000602084013e610271565b606091505b505090508061027f57600080fd5b5061028d565b61028d610191565b505050565b600061029c610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd61041a565b90506102cc565b6102cc610191565b90565b6102d7610463565b6001600160a01b0316336001600160a01b031614156101da576001600160a01b0381166103355760405162461bcd60e51b81526004018080602001828103825260368152602001806105876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61035e610463565b604080516001600160a01b03928316815291841660208301528051918290030190a16101d5816104c8565b6000610393610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd610463565b3b151590565b6103c2610463565b6001600160a01b0316336001600160a01b031614156104125760405162461bcd60e51b81526004018080602001828103825260328152602001806105556032913960400191505060405180910390fd5b6101a96101a9565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610491816104ec565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b6104f5816103b4565b6105305760405162461bcd60e51b815260040180806020018281038252603b8152602001806105bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220249c822daf23a4c4105d411560ffa6c4b3a5d68c227c3a6354de449e0b177f2264736f6c634300060c003343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100985780635c60da1b146101185780638f28397014610149578063f851a4401461017c5761005d565b3661005d5761005b610191565b005b61005b610191565b34801561007157600080fd5b5061005b6004803603602081101561008857600080fd5b50356001600160a01b03166101ab565b61005b600480360360408110156100ae57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100d957600080fd5b8201836020820111156100eb57600080fd5b8035906020019184600183028401116401000000008311171561010d57600080fd5b5090925090506101e5565b34801561012457600080fd5b5061012d610292565b604080516001600160a01b039092168252519081900360200190f35b34801561015557600080fd5b5061005b6004803603602081101561016c57600080fd5b50356001600160a01b03166102cf565b34801561018857600080fd5b5061012d610389565b6101996103ba565b6101a96101a461041a565b61043f565b565b6101b3610463565b6001600160a01b0316336001600160a01b031614156101da576101d581610488565b6101e2565b6101e2610191565b50565b6101ed610463565b6001600160a01b0316336001600160a01b031614156102855761020f83610488565b6000836001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d806000811461026c576040519150601f19603f3d011682016040523d82523d6000602084013e610271565b606091505b505090508061027f57600080fd5b5061028d565b61028d610191565b505050565b600061029c610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd61041a565b90506102cc565b6102cc610191565b90565b6102d7610463565b6001600160a01b0316336001600160a01b031614156101da576001600160a01b0381166103355760405162461bcd60e51b81526004018080602001828103825260368152602001806105876036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61035e610463565b604080516001600160a01b03928316815291841660208301528051918290030190a16101d5816104c8565b6000610393610463565b6001600160a01b0316336001600160a01b031614156102c4576102bd610463565b3b151590565b6103c2610463565b6001600160a01b0316336001600160a01b031614156104125760405162461bcd60e51b81526004018080602001828103825260328152602001806105556032913960400191505060405180910390fd5b6101a96101a9565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610491816104ec565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b6104f5816103b4565b6105305760405162461bcd60e51b815260040180806020018281038252603b8152602001806105bd603b913960400191505060405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f206164647265737343616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a2646970667358221220249c822daf23a4c4105d411560ffa6c4b3a5d68c227c3a6354de449e0b177f2264736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/CommunityLocker.dbg.json b/predeployed/src/ima_predeployed/artifacts/CommunityLocker.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/CommunityLocker.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/CommunityLocker.json b/predeployed/src/ima_predeployed/artifacts/CommunityLocker.json new file mode 100644 index 000000000..615ea3937 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/CommunityLocker.json @@ -0,0 +1,671 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "CommunityLocker", + "sourceName": "contracts/schain/CommunityLocker.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "schainHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ActivateUser", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "constantHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "ConstantUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "schainHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "LockUser", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "CONSTANT_SETTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "activeUsers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "checkAllowedToSendMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "communityPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasPriceTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newTokenManagerLinker", + "type": "address" + }, + { + "internalType": "address", + "name": "newCommunityPool", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initializeTimestamp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastMessageTimeStamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastMessageTimeStampToSchain", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mainnetGasPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gasPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "blsSignature", + "type": "uint256[2]" + }, + { + "internalType": "uint256", + "name": "hashA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hashB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + } + ], + "internalType": "struct IMessageProxy.Signature", + "name": "", + "type": "tuple" + } + ], + "name": "setGasPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chainName", + "type": "string" + }, + { + "internalType": "uint256", + "name": "newTimeLimitPerMessage", + "type": "uint256" + } + ], + "name": "setTimeLimitPerMessage", + "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": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "timeLimitPerMessage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract ITokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50611eff806100206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806359315792116100f9578063bbb9267811610097578063d547741f11610071578063d547741f146103f8578063eb0eb8ab1461040b578063f0cfb52e1461042e578063f34822b41461044e57600080fd5b8063bbb92678146103ab578063bbc4e8c2146103be578063ca15c873146103e557600080fd5b80639010d07c116100d35780639010d07c1461037457806391d1485414610387578063a217fddf1461039a578063aebc4bc3146103a257600080fd5b8063593157921461033b5780637304b44d1461034e578063884cee5a1461036157600080fd5b80632f2ff15d1161016657806345ee13821161014057806345ee1382146102c25780634fe5187c146102ca57806350f44280146102f55780635573b8b61461032857600080fd5b80632f2ff15d1461029157806336568abe146102a65780633b690b6b146102b957600080fd5b8063248a9ca3116101a2578063248a9ca31461024a57806328c5e1821461026d5780632d448928146102755780632dc151de1461027e57600080fd5b806301ffc9a7146101c957806314a7eaf6146101f157806314d140b01461021f575b600080fd5b6101dc6101d7366004611837565b610461565b60405190151581526020015b60405180910390f35b6102116101ff366004611861565b60d26020526000908152604090205481565b6040519081526020016101e8565b60cb54610232906001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b610211610258366004611861565b60009081526065602052604090206001015490565b61021161048c565b61021160d15481565b60ca54610232906001600160a01b031681565b6102a461029f36600461188f565b6104d5565b005b6102a46102b436600461188f565b6104ff565b61021160cc5481565b6102a4610582565b6102116102d836600461188f565b60d360209081526000928352604080842090915290825290205481565b61031b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516101e891906118e3565b60c954610232906001600160a01b031681565b6102a461034936600461188f565b610633565b6102a461035c366004611978565b6108e8565b6102a461036f366004611a25565b610a1c565b610232610382366004611aae565b610d76565b6101dc61039536600461188f565b610d95565b610211600081565b61021160d05481565b6102a46103b9366004611b5d565b610dc0565b6102117f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c81565b6102116103f3366004611861565b610f40565b6102a461040636600461188f565b610f57565b6101dc610419366004611ba2565b60ce6020526000908152604090205460ff1681565b61021161043c366004611ba2565b60cf6020526000908152604090205481565b6102a461045c366004611bbf565b610f7c565b60006001600160e01b03198216635a05180f60e01b14806104865750610486826111bd565b92915050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016104bc9190611c34565b6040516020818303038152906040528051906020012081565b6000828152606560205260409020600101546104f0816111f2565b6104fa83836111ff565b505050565b6001600160a01b03811633146105745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61057e8282611221565b5050565b61058d600033610d95565b6105cc5760405162461bcd60e51b815260206004820152601060248201526f24b731b7b93932b1ba1039b2b73232b960811b604482015260640161056b565b60cd5460d260006040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016106039190611c34565b6040516020818303038152906040528051906020012081526020019081526020016000208190555060cd60009055565b600082815260d3602090815260408083206001600160a01b03851684528252918290205482518084018452600781526613585a5b9b995d60ca1b818401529251859385936106819201611c34565b604051602081830303815290604052805190602001208303610720576001600160a01b038216600090815260ce602052604090205460ff166107055760405162461bcd60e51b815260206004820152601860248201527f526563697069656e74206d757374206265206163746976650000000000000000604482015260640161056b565b506001600160a01b038116600090815260cf60205260409020545b600083815260d26020526040902054429061073b9083611c66565b106107885760405162461bcd60e51b815260206004820152601b60248201527f4578636565646564206d6573736167652072617465206c696d69740000000000604482015260640161056b565b60ca546040516374a9e4c960e11b81523360048201526001600160a01b039091169063e953c99290602401602060405180830381865afa1580156107d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f49190611c87565b61084f5760405162461bcd60e51b815260206004820152602660248201527f53656e646572206973206e6f74207265676973746572656420746f6b656e206d60448201526530b730b3b2b960d11b606482015260840161056b565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200161087f9190611c34565b6040516020818303038152906040528051906020012085036108bb576001600160a01b038416600090815260cf602052604090204290556108e1565b600085815260d3602090815260408083206001600160a01b038816845290915290204290555b5050505050565b60d15482116109455760405162461bcd60e51b815260206004820152602360248201527f4761732070726963652074696d657374616d7020616c726561647920757064616044820152621d195960ea1b606482015260840161056b565b428211156109a35760405162461bcd60e51b815260206004820152602560248201527f54696d657374616d702073686f756c64206e6f7420626520696e207468652066604482015264757475726560d81b606482015260840161056b565b6040516e4d61696e6e6574476173507269636560881b6020820152602f0160408051601f19818403018152828252805160209182012060d0548452908301869052917fd9f6bd2abae0f2a51b3f5ffb29e0e35ee9ad2e3921ede0d71bff21dc8609f6f1910160405180910390a25060d09190915560d155565b60c9546001600160a01b03163314610a765760405162461bcd60e51b815260206004820152601d60248201527f53656e646572206973206e6f742061206d6573736167652070726f7879000000604482015260640161056b565b60cb546001600160a01b03848116911614610ad35760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520436f6d6d756e697479506f6f6c00000000604482015260640161056b565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610b039190611c34565b604051602081830303815290604052805190602001208414610b715760405162461bcd60e51b815260206004820152602160248201527f536f7572636520636861696e206e616d65206d757374206265204d61696e6e656044820152601d60fa1b606482015260840161056b565b6000610b7d8383611243565b9050600781600e811115610b9357610b93611ca4565b14610bf45760405162461bcd60e51b815260206004820152602b60248201527f546865206d6573736167652073686f756c6420636f6e7461696e20612073746160448201526a3a3ab99037b3103ab9b2b960a91b606482015260840161056b565b6000610c00848461128e565b6040808201516020808401516001600160a01b0316600090815260ce9091529190912054919250151560ff909116151503610c8c5760405162461bcd60e51b815260206004820152602660248201527f4163746976652075736572207374617475736573206d7573742062652064696660448201526519995c995b9d60d21b606482015260840161056b565b604081810180516020808501516001600160a01b0316600090815260ce90915292909220805460ff1916921515929092179091555115610d1c577fdacccea96400d48c51a00ff7af4d1c6b6ac4909bbff0fe495f0e0edc298c3dde60cc548260200151604051610d0f9291909182526001600160a01b0316602082015260400190565b60405180910390a1610d6e565b7f01d8973c54faac85b2cfd40f935f8da4261d9883283ad73ce0e10aa91fc37bdf60cc548260200151604051610d659291909182526001600160a01b0316602082015260400190565b60405180910390a15b505050505050565b6000828152609760205260408120610d8e9083611327565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610dea7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33610d95565b610e455760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2073657420636f6044820152651b9cdd185b9d60d21b606482015260840161056b565b600082604051602001610e589190611c34565b60405160208183030381529060405280519060200120905060cc548103610eb35760405162461bcd60e51b815260206004820152600f60248201526e24b731b7b93932b1ba1031b430b4b760891b604482015260640161056b565b6040517254696d654c696d69745065724d65737361676560681b602082015260330160408051808303601f190181528282528051602091820120600085815260d28352839020548452908301859052917fd9f6bd2abae0f2a51b3f5ffb29e0e35ee9ad2e3921ede0d71bff21dc8609f6f1910160405180910390a2600090815260d2602052604090205550565b600081815260976020526040812061048690611333565b600082815260656020526040902060010154610f72816111f2565b6104fa8383611221565b600054610100900460ff1615808015610f9c5750600054600160ff909116105b80610fb65750303b158015610fb6575060005460ff166001145b6110195760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161056b565b6000805460ff19166001179055801561103c576000805461ff0019166101001790555b6001600160a01b0382166110925760405162461bcd60e51b815260206004820152601a60248201527f4e6f646520616464726573732068617320746f20626520736574000000000000604482015260640161056b565b61109a61133d565b6110a56000336113aa565b60c980546001600160a01b038087166001600160a01b03199283161790925560ca8054928616929091169190911790556040516110e6908690602001611c34565b60408051601f19818403018152828252805160209182012060cc558282018252600783526613585a5b9b995d60ca1b83820152905161012c9260d292600092611130929101611c34565b60408051808303601f190181529181528151602092830120835290820192909252016000205560cb80546001600160a01b0319166001600160a01b03841617905580156108e1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006001600160e01b03198216637965db0b60e01b148061048657506301ffc9a760e01b6001600160e01b0319831614610486565b6111fc81336113b4565b50565b6112098282611418565b60008281526097602052604090206104fa908261149e565b61122b82826114b3565b60008281526097602052604090206104fa908261151a565b60008061125283850185611861565b905061125f602082611cba565b6000036112825761127a61127584838188611cdc565b611243565b915050610486565b61127a83850185611d1a565b604080516080810182526000606082018181528252602082018190529181019190915260076112bd8484611243565b600e8111156112ce576112ce611ca4565b1461131b5760405162461bcd60e51b815260206004820152601f60248201527f4d6573736167652074797065206973206e6f7420557365722053746174757300604482015260640161056b565b610d8e82840184611d35565b6000610d8e838361152f565b6000610486825490565b600054610100900460ff166113a85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161056b565b565b61057e82826111ff565b6113be8282610d95565b61057e576113d6816001600160a01b03166014611559565b6113e1836020611559565b6040516020016113f2929190611ddf565b60408051601f198184030181529082905262461bcd60e51b825261056b916004016118e3565b6114228282610d95565b61057e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561145a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610d8e836001600160a01b0384166116f5565b6114bd8282610d95565b1561057e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610d8e836001600160a01b038416611744565b600082600001828154811061154657611546611e54565b9060005260206000200154905092915050565b60606000611568836002611e6a565b611573906002611c66565b67ffffffffffffffff81111561158b5761158b611916565b6040519080825280601f01601f1916602001820160405280156115b5576020820181803683370190505b509050600360fc1b816000815181106115d0576115d0611e54565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106115ff576115ff611e54565b60200101906001600160f81b031916908160001a9053506000611623846002611e6a565b61162e906001611c66565b90505b60018111156116a6576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061166257611662611e54565b1a60f81b82828151811061167857611678611e54565b60200101906001600160f81b031916908160001a90535060049490941c9361169f81611e89565b9050611631565b508315610d8e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161056b565b600081815260018301602052604081205461173c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610486565b506000610486565b6000818152600183016020526040812054801561182d576000611768600183611ea0565b855490915060009061177c90600190611ea0565b90508181146117e157600086600001828154811061179c5761179c611e54565b90600052602060002001549050808760000184815481106117bf576117bf611e54565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806117f2576117f2611eb3565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610486565b6000915050610486565b60006020828403121561184957600080fd5b81356001600160e01b031981168114610d8e57600080fd5b60006020828403121561187357600080fd5b5035919050565b6001600160a01b03811681146111fc57600080fd5b600080604083850312156118a257600080fd5b8235915060208301356118b48161187a565b809150509250929050565b60005b838110156118da5781810151838201526020016118c2565b50506000910152565b60208152600082518060208401526119028160408501602087016118bf565b601f01601f19169190910160400192915050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561194f5761194f611916565b60405290565b6040805190810167ffffffffffffffff8111828210171561194f5761194f611916565b600080600083850360e081121561198e57600080fd5b84359350602080860135935060a0603f19830112156119ac57600080fd5b6119b461192c565b915086605f8701126119c557600080fd5b6119cd611955565b8060808801898111156119df57600080fd5b604089015b818110156119fb57803584529284019284016119e4565b5090845235918301919091525060a0850135604082015260c0909401356060850152509093909250565b60008060008060608587031215611a3b57600080fd5b843593506020850135611a4d8161187a565b9250604085013567ffffffffffffffff80821115611a6a57600080fd5b818701915087601f830112611a7e57600080fd5b813581811115611a8d57600080fd5b886020828501011115611a9f57600080fd5b95989497505060200194505050565b60008060408385031215611ac157600080fd5b50508035926020909101359150565b600082601f830112611ae157600080fd5b813567ffffffffffffffff80821115611afc57611afc611916565b604051601f8301601f19908116603f01168101908282118183101715611b2457611b24611916565b81604052838152866020858801011115611b3d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215611b7057600080fd5b823567ffffffffffffffff811115611b8757600080fd5b611b9385828601611ad0565b95602094909401359450505050565b600060208284031215611bb457600080fd5b8135610d8e8161187a565b60008060008060808587031215611bd557600080fd5b843567ffffffffffffffff811115611bec57600080fd5b611bf887828801611ad0565b9450506020850135611c098161187a565b92506040850135611c198161187a565b91506060850135611c298161187a565b939692955090935050565b60008251611c468184602087016118bf565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561048657610486611c50565b80151581146111fc57600080fd5b600060208284031215611c9957600080fd5b8151610d8e81611c79565b634e487b7160e01b600052602160045260246000fd5b600082611cd757634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115611cec57600080fd5b83861115611cf957600080fd5b5050820193919092039150565b8035600f8110611d1557600080fd5b919050565b600060208284031215611d2c57600080fd5b610d8e82611d06565b60008183036060811215611d4857600080fd5b6040516060810167ffffffffffffffff8282108183111715611d6c57611d6c611916565b816040526020841215611d7e57600080fd5b6080830193508184108185111715611d9857611d98611916565b5082604052611da685611d06565b8152815260208401359150611dba8261187a565b81602082015260408401359150611dd082611c79565b60408101919091529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611e178160178501602088016118bf565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611e488160288401602088016118bf565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615611e8457611e84611c50565b500290565b600081611e9857611e98611c50565b506000190190565b8181038181111561048657610486611c50565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ffc2ba8b3668b63157574c2cfb07fd5725d38150fb0554a17a997986fd16016364736f6c63430008100033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806359315792116100f9578063bbb9267811610097578063d547741f11610071578063d547741f146103f8578063eb0eb8ab1461040b578063f0cfb52e1461042e578063f34822b41461044e57600080fd5b8063bbb92678146103ab578063bbc4e8c2146103be578063ca15c873146103e557600080fd5b80639010d07c116100d35780639010d07c1461037457806391d1485414610387578063a217fddf1461039a578063aebc4bc3146103a257600080fd5b8063593157921461033b5780637304b44d1461034e578063884cee5a1461036157600080fd5b80632f2ff15d1161016657806345ee13821161014057806345ee1382146102c25780634fe5187c146102ca57806350f44280146102f55780635573b8b61461032857600080fd5b80632f2ff15d1461029157806336568abe146102a65780633b690b6b146102b957600080fd5b8063248a9ca3116101a2578063248a9ca31461024a57806328c5e1821461026d5780632d448928146102755780632dc151de1461027e57600080fd5b806301ffc9a7146101c957806314a7eaf6146101f157806314d140b01461021f575b600080fd5b6101dc6101d7366004611837565b610461565b60405190151581526020015b60405180910390f35b6102116101ff366004611861565b60d26020526000908152604090205481565b6040519081526020016101e8565b60cb54610232906001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b610211610258366004611861565b60009081526065602052604090206001015490565b61021161048c565b61021160d15481565b60ca54610232906001600160a01b031681565b6102a461029f36600461188f565b6104d5565b005b6102a46102b436600461188f565b6104ff565b61021160cc5481565b6102a4610582565b6102116102d836600461188f565b60d360209081526000928352604080842090915290825290205481565b61031b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516101e891906118e3565b60c954610232906001600160a01b031681565b6102a461034936600461188f565b610633565b6102a461035c366004611978565b6108e8565b6102a461036f366004611a25565b610a1c565b610232610382366004611aae565b610d76565b6101dc61039536600461188f565b610d95565b610211600081565b61021160d05481565b6102a46103b9366004611b5d565b610dc0565b6102117f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c81565b6102116103f3366004611861565b610f40565b6102a461040636600461188f565b610f57565b6101dc610419366004611ba2565b60ce6020526000908152604090205460ff1681565b61021161043c366004611ba2565b60cf6020526000908152604090205481565b6102a461045c366004611bbf565b610f7c565b60006001600160e01b03198216635a05180f60e01b14806104865750610486826111bd565b92915050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016104bc9190611c34565b6040516020818303038152906040528051906020012081565b6000828152606560205260409020600101546104f0816111f2565b6104fa83836111ff565b505050565b6001600160a01b03811633146105745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61057e8282611221565b5050565b61058d600033610d95565b6105cc5760405162461bcd60e51b815260206004820152601060248201526f24b731b7b93932b1ba1039b2b73232b960811b604482015260640161056b565b60cd5460d260006040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016106039190611c34565b6040516020818303038152906040528051906020012081526020019081526020016000208190555060cd60009055565b600082815260d3602090815260408083206001600160a01b03851684528252918290205482518084018452600781526613585a5b9b995d60ca1b818401529251859385936106819201611c34565b604051602081830303815290604052805190602001208303610720576001600160a01b038216600090815260ce602052604090205460ff166107055760405162461bcd60e51b815260206004820152601860248201527f526563697069656e74206d757374206265206163746976650000000000000000604482015260640161056b565b506001600160a01b038116600090815260cf60205260409020545b600083815260d26020526040902054429061073b9083611c66565b106107885760405162461bcd60e51b815260206004820152601b60248201527f4578636565646564206d6573736167652072617465206c696d69740000000000604482015260640161056b565b60ca546040516374a9e4c960e11b81523360048201526001600160a01b039091169063e953c99290602401602060405180830381865afa1580156107d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f49190611c87565b61084f5760405162461bcd60e51b815260206004820152602660248201527f53656e646572206973206e6f74207265676973746572656420746f6b656e206d60448201526530b730b3b2b960d11b606482015260840161056b565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200161087f9190611c34565b6040516020818303038152906040528051906020012085036108bb576001600160a01b038416600090815260cf602052604090204290556108e1565b600085815260d3602090815260408083206001600160a01b038816845290915290204290555b5050505050565b60d15482116109455760405162461bcd60e51b815260206004820152602360248201527f4761732070726963652074696d657374616d7020616c726561647920757064616044820152621d195960ea1b606482015260840161056b565b428211156109a35760405162461bcd60e51b815260206004820152602560248201527f54696d657374616d702073686f756c64206e6f7420626520696e207468652066604482015264757475726560d81b606482015260840161056b565b6040516e4d61696e6e6574476173507269636560881b6020820152602f0160408051601f19818403018152828252805160209182012060d0548452908301869052917fd9f6bd2abae0f2a51b3f5ffb29e0e35ee9ad2e3921ede0d71bff21dc8609f6f1910160405180910390a25060d09190915560d155565b60c9546001600160a01b03163314610a765760405162461bcd60e51b815260206004820152601d60248201527f53656e646572206973206e6f742061206d6573736167652070726f7879000000604482015260640161056b565b60cb546001600160a01b03848116911614610ad35760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520436f6d6d756e697479506f6f6c00000000604482015260640161056b565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610b039190611c34565b604051602081830303815290604052805190602001208414610b715760405162461bcd60e51b815260206004820152602160248201527f536f7572636520636861696e206e616d65206d757374206265204d61696e6e656044820152601d60fa1b606482015260840161056b565b6000610b7d8383611243565b9050600781600e811115610b9357610b93611ca4565b14610bf45760405162461bcd60e51b815260206004820152602b60248201527f546865206d6573736167652073686f756c6420636f6e7461696e20612073746160448201526a3a3ab99037b3103ab9b2b960a91b606482015260840161056b565b6000610c00848461128e565b6040808201516020808401516001600160a01b0316600090815260ce9091529190912054919250151560ff909116151503610c8c5760405162461bcd60e51b815260206004820152602660248201527f4163746976652075736572207374617475736573206d7573742062652064696660448201526519995c995b9d60d21b606482015260840161056b565b604081810180516020808501516001600160a01b0316600090815260ce90915292909220805460ff1916921515929092179091555115610d1c577fdacccea96400d48c51a00ff7af4d1c6b6ac4909bbff0fe495f0e0edc298c3dde60cc548260200151604051610d0f9291909182526001600160a01b0316602082015260400190565b60405180910390a1610d6e565b7f01d8973c54faac85b2cfd40f935f8da4261d9883283ad73ce0e10aa91fc37bdf60cc548260200151604051610d659291909182526001600160a01b0316602082015260400190565b60405180910390a15b505050505050565b6000828152609760205260408120610d8e9083611327565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610dea7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33610d95565b610e455760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2073657420636f6044820152651b9cdd185b9d60d21b606482015260840161056b565b600082604051602001610e589190611c34565b60405160208183030381529060405280519060200120905060cc548103610eb35760405162461bcd60e51b815260206004820152600f60248201526e24b731b7b93932b1ba1031b430b4b760891b604482015260640161056b565b6040517254696d654c696d69745065724d65737361676560681b602082015260330160408051808303601f190181528282528051602091820120600085815260d28352839020548452908301859052917fd9f6bd2abae0f2a51b3f5ffb29e0e35ee9ad2e3921ede0d71bff21dc8609f6f1910160405180910390a2600090815260d2602052604090205550565b600081815260976020526040812061048690611333565b600082815260656020526040902060010154610f72816111f2565b6104fa8383611221565b600054610100900460ff1615808015610f9c5750600054600160ff909116105b80610fb65750303b158015610fb6575060005460ff166001145b6110195760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161056b565b6000805460ff19166001179055801561103c576000805461ff0019166101001790555b6001600160a01b0382166110925760405162461bcd60e51b815260206004820152601a60248201527f4e6f646520616464726573732068617320746f20626520736574000000000000604482015260640161056b565b61109a61133d565b6110a56000336113aa565b60c980546001600160a01b038087166001600160a01b03199283161790925560ca8054928616929091169190911790556040516110e6908690602001611c34565b60408051601f19818403018152828252805160209182012060cc558282018252600783526613585a5b9b995d60ca1b83820152905161012c9260d292600092611130929101611c34565b60408051808303601f190181529181528151602092830120835290820192909252016000205560cb80546001600160a01b0319166001600160a01b03841617905580156108e1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006001600160e01b03198216637965db0b60e01b148061048657506301ffc9a760e01b6001600160e01b0319831614610486565b6111fc81336113b4565b50565b6112098282611418565b60008281526097602052604090206104fa908261149e565b61122b82826114b3565b60008281526097602052604090206104fa908261151a565b60008061125283850185611861565b905061125f602082611cba565b6000036112825761127a61127584838188611cdc565b611243565b915050610486565b61127a83850185611d1a565b604080516080810182526000606082018181528252602082018190529181019190915260076112bd8484611243565b600e8111156112ce576112ce611ca4565b1461131b5760405162461bcd60e51b815260206004820152601f60248201527f4d6573736167652074797065206973206e6f7420557365722053746174757300604482015260640161056b565b610d8e82840184611d35565b6000610d8e838361152f565b6000610486825490565b600054610100900460ff166113a85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161056b565b565b61057e82826111ff565b6113be8282610d95565b61057e576113d6816001600160a01b03166014611559565b6113e1836020611559565b6040516020016113f2929190611ddf565b60408051601f198184030181529082905262461bcd60e51b825261056b916004016118e3565b6114228282610d95565b61057e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561145a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610d8e836001600160a01b0384166116f5565b6114bd8282610d95565b1561057e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610d8e836001600160a01b038416611744565b600082600001828154811061154657611546611e54565b9060005260206000200154905092915050565b60606000611568836002611e6a565b611573906002611c66565b67ffffffffffffffff81111561158b5761158b611916565b6040519080825280601f01601f1916602001820160405280156115b5576020820181803683370190505b509050600360fc1b816000815181106115d0576115d0611e54565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106115ff576115ff611e54565b60200101906001600160f81b031916908160001a9053506000611623846002611e6a565b61162e906001611c66565b90505b60018111156116a6576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061166257611662611e54565b1a60f81b82828151811061167857611678611e54565b60200101906001600160f81b031916908160001a90535060049490941c9361169f81611e89565b9050611631565b508315610d8e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161056b565b600081815260018301602052604081205461173c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610486565b506000610486565b6000818152600183016020526040812054801561182d576000611768600183611ea0565b855490915060009061177c90600190611ea0565b90508181146117e157600086600001828154811061179c5761179c611e54565b90600052602060002001549050808760000184815481106117bf576117bf611e54565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806117f2576117f2611eb3565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610486565b6000915050610486565b60006020828403121561184957600080fd5b81356001600160e01b031981168114610d8e57600080fd5b60006020828403121561187357600080fd5b5035919050565b6001600160a01b03811681146111fc57600080fd5b600080604083850312156118a257600080fd5b8235915060208301356118b48161187a565b809150509250929050565b60005b838110156118da5781810151838201526020016118c2565b50506000910152565b60208152600082518060208401526119028160408501602087016118bf565b601f01601f19169190910160400192915050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561194f5761194f611916565b60405290565b6040805190810167ffffffffffffffff8111828210171561194f5761194f611916565b600080600083850360e081121561198e57600080fd5b84359350602080860135935060a0603f19830112156119ac57600080fd5b6119b461192c565b915086605f8701126119c557600080fd5b6119cd611955565b8060808801898111156119df57600080fd5b604089015b818110156119fb57803584529284019284016119e4565b5090845235918301919091525060a0850135604082015260c0909401356060850152509093909250565b60008060008060608587031215611a3b57600080fd5b843593506020850135611a4d8161187a565b9250604085013567ffffffffffffffff80821115611a6a57600080fd5b818701915087601f830112611a7e57600080fd5b813581811115611a8d57600080fd5b886020828501011115611a9f57600080fd5b95989497505060200194505050565b60008060408385031215611ac157600080fd5b50508035926020909101359150565b600082601f830112611ae157600080fd5b813567ffffffffffffffff80821115611afc57611afc611916565b604051601f8301601f19908116603f01168101908282118183101715611b2457611b24611916565b81604052838152866020858801011115611b3d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215611b7057600080fd5b823567ffffffffffffffff811115611b8757600080fd5b611b9385828601611ad0565b95602094909401359450505050565b600060208284031215611bb457600080fd5b8135610d8e8161187a565b60008060008060808587031215611bd557600080fd5b843567ffffffffffffffff811115611bec57600080fd5b611bf887828801611ad0565b9450506020850135611c098161187a565b92506040850135611c198161187a565b91506060850135611c298161187a565b939692955090935050565b60008251611c468184602087016118bf565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561048657610486611c50565b80151581146111fc57600080fd5b600060208284031215611c9957600080fd5b8151610d8e81611c79565b634e487b7160e01b600052602160045260246000fd5b600082611cd757634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115611cec57600080fd5b83861115611cf957600080fd5b5050820193919092039150565b8035600f8110611d1557600080fd5b919050565b600060208284031215611d2c57600080fd5b610d8e82611d06565b60008183036060811215611d4857600080fd5b6040516060810167ffffffffffffffff8282108183111715611d6c57611d6c611916565b816040526020841215611d7e57600080fd5b6080830193508184108185111715611d9857611d98611916565b5082604052611da685611d06565b8152815260208401359150611dba8261187a565b81602082015260408401359150611dd082611c79565b60408101919091529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611e178160178501602088016118bf565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611e488160288401602088016118bf565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615611e8457611e84611c50565b500290565b600081611e9857611e98611c50565b506000190190565b8181038181111561048657610486611c50565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ffc2ba8b3668b63157574c2cfb07fd5725d38150fb0554a17a997986fd16016364736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/CommunityLocker.meta.json b/predeployed/src/ima_predeployed/artifacts/CommunityLocker.meta.json new file mode 100644 index 000000000..d2175c6f4 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/CommunityLocker.meta.json @@ -0,0 +1,410 @@ +{ + "name": "CommunityLocker", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.dbg.json b/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.json b/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.json new file mode 100644 index 000000000..ebcabc34d --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.json @@ -0,0 +1,690 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ERC1155OnChain", + "sourceName": "contracts/schain/tokens/ERC1155OnChain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "uri", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "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": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "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": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "burnBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mintBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "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": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b5060405162002ecd38038062002ecd8339810160408190526200003491620004ed565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d760201b620009121760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e660201b620009211760201c565b6200013d826200024460201b6200094a1760201c565b62000152620001e660201b620009211760201c565b6200016d60008051602062002ead83398151915280620002ae565b6200018860008051602062002ead83398151915233620002f9565b8015620001cf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50506200071c565b6001600160a01b03163b151590565b600054610100900460ff16620002425760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a05760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab8162000309565b50565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b62000305828262000370565b5050565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab81620003b3565b620003878282620003c160201b6200097d1760201c565b6000828152609760209081526040909120620003ae91839062000a0362000465821b17901c565b505050565b60cb62000305828262000650565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620003055760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004213390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200047c836001600160a01b03841662000485565b90505b92915050565b6000818152600183016020526040812054620004ce575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200047f565b5060006200047f565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156200050157600080fd5b82516001600160401b03808211156200051957600080fd5b818501915085601f8301126200052e57600080fd5b815181811115620005435762000543620004d7565b604051601f8201601f19908116603f011681019083821181831017156200056e576200056e620004d7565b8160405282815288868487010111156200058757600080fd5b600093505b82841015620005ab57848401860151818501870152928501926200058c565b600086848301015280965050505050505092915050565b600181811c90821680620005d757607f821691505b602082108103620005f857634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003ae57600081815260208120601f850160051c81016020861015620006275750805b601f850160051c820191505b81811015620006485782815560010162000633565b505050505050565b81516001600160401b038111156200066c576200066c620004d7565b62000684816200067d8454620005c2565b84620005fe565b602080601f831160018114620006bc5760008415620006a35750858301515b600019600386901b1c1916600185901b17855562000648565b600085815260208120601f198616915b82811015620006ed57888601518255948401946001909101908401620006cc565b50858210156200070c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612761806200072c6000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c873146102b4578063d5391393146102c7578063d547741f146102ee578063e985e9c514610301578063f242432a1461033d578063f5298aca1461035057600080fd5b8063731133e9146102485780639010d07c1461025b57806391d1485414610286578063a217fddf14610299578063a22cb465146102a157600080fd5b80632eb2c2d6116100ff5780632eb2c2d6146101dc5780632f2ff15d146101ef57806336568abe146102025780634e1273f4146102155780636b20c4541461023557600080fd5b8062fdd58e1461013b57806301ffc9a7146101615780630e89341c146101845780631f7fdffa146101a4578063248a9ca3146101b9575b600080fd5b61014e610149366004611a1f565b610363565b6040519081526020015b60405180910390f35b61017461016f366004611a5f565b6103fe565b6040519015158152602001610158565b610197610192366004611a7c565b610409565b6040516101589190611ae5565b6101b76101b2366004611c41565b61049d565b005b61014e6101c7366004611a7c565b60009081526065602052604090206001015490565b6101b76101ea366004611cd9565b61051e565b6101b76101fd366004611d82565b61056a565b6101b7610210366004611d82565b610594565b610228610223366004611dae565b610612565b6040516101589190611eb3565b6101b7610243366004611ec6565b61073b565b6101b7610256366004611f39565b61077e565b61026e610269366004611f8d565b6107f9565b6040516001600160a01b039091168152602001610158565b610174610294366004611d82565b610818565b61014e600081565b6101b76102af366004611faf565b610843565b61014e6102c2366004611a7c565b61084e565b61014e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101b76102fc366004611d82565b610865565b61017461030f366004611feb565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205460ff1690565b6101b761034b366004612015565b61088a565b6101b761035e366004612079565b6108cf565b60006001600160a01b0383166103d35760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b50600081815260c9602090815260408083206001600160a01b03861684529091529020545b92915050565b60006103f882610a18565b606060cb8054610418906120ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610444906120ac565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b50505050509050919050565b6104c77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b61050c5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610a58565b50505050565b6001600160a01b03851633148061053a575061053a853361030f565b6105565760405162461bcd60e51b81526004016103ca906120e6565b6105638585858585610ba4565b5050505050565b60008281526065602052604090206001015461058581610d43565b61058f8383610d4d565b505050565b6001600160a01b03811633146106045760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016103ca565b61060e8282610d6f565b5050565b606081518351146106775760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016103ca565b600083516001600160401b0381111561069257610692611af8565b6040519080825280602002602001820160405280156106bb578160200160208202803683370190505b50905060005b8451811015610733576107068582815181106106df576106df612135565b60200260200101518583815181106106f9576106f9612135565b6020026020010151610363565b82828151811061071857610718612135565b602090810291909101015261072c81612161565b90506106c1565b509392505050565b6001600160a01b0383163314806107575750610757833361030f565b6107735760405162461bcd60e51b81526004016103ca906120e6565b61058f838383610d91565b6107a87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b6107ed5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610f1e565b60008281526097602052604081206108119083610ffa565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61060e338383611006565b60008181526097602052604081206103f8906110e6565b60008281526065602052604090206001015461088081610d43565b61058f8383610d6f565b6001600160a01b0385163314806108a657506108a6853361030f565b6108c25760405162461bcd60e51b81526004016103ca906120e6565b61056385858585856110f0565b6001600160a01b0383163314806108eb57506108eb833361030f565b6109075760405162461bcd60e51b81526004016103ca906120e6565b61058f83838361121e565b6001600160a01b03163b151590565b600054610100900460ff166109485760405162461bcd60e51b81526004016103ca9061217a565b565b600054610100900460ff166109715760405162461bcd60e51b81526004016103ca9061217a565b61097a81611325565b50565b6109878282610818565b61060e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556109bf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610811836001600160a01b038416611355565b60006001600160e01b03198216636cdb3d1360e11b1480610a4957506001600160e01b031982166303a24d0760e21b145b806103f857506103f8826113a4565b6001600160a01b038416610a7e5760405162461bcd60e51b81526004016103ca906121c5565b8151835114610a9f5760405162461bcd60e51b81526004016103ca90612206565b3360005b8451811015610b3c57838181518110610abe57610abe612135565b602002602001015160c96000878481518110610adc57610adc612135565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254610b24919061224e565b90915550819050610b3481612161565b915050610aa3565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610b8d929190612261565b60405180910390a4610563816000878787876113c9565b8151835114610bc55760405162461bcd60e51b81526004016103ca90612206565b6001600160a01b038416610beb5760405162461bcd60e51b81526004016103ca9061228f565b3360005b8451811015610cd5576000858281518110610c0c57610c0c612135565b602002602001015190506000858381518110610c2a57610c2a612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038e168352909352919091205490915081811015610c7b5760405162461bcd60e51b81526004016103ca906122d4565b600083815260c9602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290610cba90849061224e565b9250508190555050505080610cce90612161565b9050610bef565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d25929190612261565b60405180910390a4610d3b8187878787876113c9565b505050505050565b61097a8133611524565b610d57828261097d565b600082815260976020526040902061058f9082610a03565b610d798282611588565b600082815260976020526040902061058f90826115ef565b6001600160a01b038316610db75760405162461bcd60e51b81526004016103ca9061231e565b8051825114610dd85760405162461bcd60e51b81526004016103ca90612206565b604080516020810190915260009081905233905b8351811015610eb1576000848281518110610e0957610e09612135565b602002602001015190506000848381518110610e2757610e27612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038c168352909352919091205490915081811015610e785760405162461bcd60e51b81526004016103ca90612361565b600092835260c9602090815260408085206001600160a01b038b1686529091529092209103905580610ea981612161565b915050610dec565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610f02929190612261565b60405180910390a4604080516020810190915260009052610518565b6001600160a01b038416610f445760405162461bcd60e51b81526004016103ca906121c5565b336000610f5085611604565b90506000610f5d85611604565b9050600086815260c9602090815260408083206001600160a01b038b16845290915281208054879290610f9190849061224e565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610ff18360008989898961164f565b50505050505050565b6000610811838361170a565b816001600160a01b0316836001600160a01b0316036110795760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016103ca565b6001600160a01b03838116600081815260ca6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006103f8825490565b6001600160a01b0384166111165760405162461bcd60e51b81526004016103ca9061228f565b33600061112285611604565b9050600061112f85611604565b9050600086815260c9602090815260408083206001600160a01b038c168452909152902054858110156111745760405162461bcd60e51b81526004016103ca906122d4565b600087815260c9602090815260408083206001600160a01b038d8116855292528083208985039055908a168252812080548892906111b390849061224e565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611213848a8a8a8a8a61164f565b505050505050505050565b6001600160a01b0383166112445760405162461bcd60e51b81526004016103ca9061231e565b33600061125084611604565b9050600061125d84611604565b604080516020808201835260009182905288825260c981528282206001600160a01b038b16835290522054909150848110156112ab5760405162461bcd60e51b81526004016103ca90612361565b600086815260c9602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4604080516020810190915260009052610ff1565b600054610100900460ff1661134c5760405162461bcd60e51b81526004016103ca9061217a565b61097a81611734565b600081815260018301602052604081205461139c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103f8565b5060006103f8565b60006001600160e01b03198216635a05180f60e01b14806103f857506103f882611740565b6001600160a01b0384163b15610d3b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061140d90899089908890889088906004016123a5565b6020604051808303816000875af1925050508015611448575060408051601f3d908101601f1916820190925261144591810190612403565b60015b6114f457611454612420565b806308c379a00361148d575061146861243c565b80611473575061148f565b8060405162461bcd60e51b81526004016103ca9190611ae5565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016103ca565b6001600160e01b0319811663bc197c8160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b61152e8282610818565b61060e57611546816001600160a01b03166014611775565b611551836020611775565b60405160200161156292919061250d565b60408051601f198184030181529082905262461bcd60e51b82526103ca91600401611ae5565b6115928282610818565b1561060e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610811836001600160a01b038416611910565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061163e5761163e612135565b602090810291909101015292915050565b6001600160a01b0384163b15610d3b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906116939089908990889088908890600401612582565b6020604051808303816000875af19250505080156116ce575060408051601f3d908101601f191682019092526116cb91810190612403565b60015b6116da57611454612420565b6001600160e01b0319811663f23a6e6160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b600082600001828154811061172157611721612135565b9060005260206000200154905092915050565b60cb61060e828261260d565b60006001600160e01b03198216637965db0b60e01b14806103f857506301ffc9a760e01b6001600160e01b03198316146103f8565b606060006117848360026126cc565b61178f90600261224e565b6001600160401b038111156117a6576117a6611af8565b6040519080825280601f01601f1916602001820160405280156117d0576020820181803683370190505b509050600360fc1b816000815181106117eb576117eb612135565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061181a5761181a612135565b60200101906001600160f81b031916908160001a905350600061183e8460026126cc565b61184990600161224e565b90505b60018111156118c1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061187d5761187d612135565b1a60f81b82828151811061189357611893612135565b60200101906001600160f81b031916908160001a90535060049490941c936118ba816126eb565b905061184c565b5083156108115760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016103ca565b600081815260018301602052604081205480156119f9576000611934600183612702565b855490915060009061194890600190612702565b90508181146119ad57600086600001828154811061196857611968612135565b906000526020600020015490508087600001848154811061198b5761198b612135565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119be576119be612715565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103f8565b60009150506103f8565b80356001600160a01b0381168114611a1a57600080fd5b919050565b60008060408385031215611a3257600080fd5b611a3b83611a03565b946020939093013593505050565b6001600160e01b03198116811461097a57600080fd5b600060208284031215611a7157600080fd5b813561081181611a49565b600060208284031215611a8e57600080fd5b5035919050565b60005b83811015611ab0578181015183820152602001611a98565b50506000910152565b60008151808452611ad1816020860160208601611a95565b601f01601f19169290920160200192915050565b6020815260006108116020830184611ab9565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715611b3357611b33611af8565b6040525050565b60006001600160401b03821115611b5357611b53611af8565b5060051b60200190565b600082601f830112611b6e57600080fd5b81356020611b7b82611b3a565b604051611b888282611b0e565b83815260059390931b8501820192828101915086841115611ba857600080fd5b8286015b84811015611bc35780358352918301918301611bac565b509695505050505050565b600082601f830112611bdf57600080fd5b81356001600160401b03811115611bf857611bf8611af8565b604051611c0f601f8301601f191660200182611b0e565b818152846020838601011115611c2457600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611c5757600080fd5b611c6085611a03565b935060208501356001600160401b0380821115611c7c57600080fd5b611c8888838901611b5d565b94506040870135915080821115611c9e57600080fd5b611caa88838901611b5d565b93506060870135915080821115611cc057600080fd5b50611ccd87828801611bce565b91505092959194509250565b600080600080600060a08688031215611cf157600080fd5b611cfa86611a03565b9450611d0860208701611a03565b935060408601356001600160401b0380821115611d2457600080fd5b611d3089838a01611b5d565b94506060880135915080821115611d4657600080fd5b611d5289838a01611b5d565b93506080880135915080821115611d6857600080fd5b50611d7588828901611bce565b9150509295509295909350565b60008060408385031215611d9557600080fd5b82359150611da560208401611a03565b90509250929050565b60008060408385031215611dc157600080fd5b82356001600160401b0380821115611dd857600080fd5b818501915085601f830112611dec57600080fd5b81356020611df982611b3a565b604051611e068282611b0e565b83815260059390931b8501820192828101915089841115611e2657600080fd5b948201945b83861015611e4b57611e3c86611a03565b82529482019490820190611e2b565b96505086013592505080821115611e6157600080fd5b50611e6e85828601611b5d565b9150509250929050565b600081518084526020808501945080840160005b83811015611ea857815187529582019590820190600101611e8c565b509495945050505050565b6020815260006108116020830184611e78565b600080600060608486031215611edb57600080fd5b611ee484611a03565b925060208401356001600160401b0380821115611f0057600080fd5b611f0c87838801611b5d565b93506040860135915080821115611f2257600080fd5b50611f2f86828701611b5d565b9150509250925092565b60008060008060808587031215611f4f57600080fd5b611f5885611a03565b9350602085013592506040850135915060608501356001600160401b03811115611f8157600080fd5b611ccd87828801611bce565b60008060408385031215611fa057600080fd5b50508035926020909101359150565b60008060408385031215611fc257600080fd5b611fcb83611a03565b915060208301358015158114611fe057600080fd5b809150509250929050565b60008060408385031215611ffe57600080fd5b61200783611a03565b9150611da560208401611a03565b600080600080600060a0868803121561202d57600080fd5b61203686611a03565b945061204460208701611a03565b9350604086013592506060860135915060808601356001600160401b0381111561206d57600080fd5b611d7588828901611bce565b60008060006060848603121561208e57600080fd5b61209784611a03565b95602085013595506040909401359392505050565b600181811c908216806120c057607f821691505b6020821081036120e057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602f908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526e195c881b9bdc88185c1c1c9bdd9959608a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016121735761217361214b565b5060010190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b808201808211156103f8576103f861214b565b6040815260006122746040830185611e78565b82810360208401526122868185611e78565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526023908201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526024908201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604082015263616e636560e01b606082015260800190565b6001600160a01b0386811682528516602082015260a0604082018190526000906123d190830186611e78565b82810360608401526123e38186611e78565b905082810360808401526123f78185611ab9565b98975050505050505050565b60006020828403121561241557600080fd5b815161081181611a49565b600060033d11156124395760046000803e5060005160e01c5b90565b600060443d101561244a5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561247957505050505090565b82850191508151818111156124915750505050505090565b843d87010160208285010111156124ab5750505050505090565b6124ba60208286010187611b0e565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612545816017850160208801611a95565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612576816028840160208801611a95565b01602801949350505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906125bc90830184611ab9565b979650505050505050565b601f82111561058f57600081815260208120601f850160051c810160208610156125ee5750805b601f850160051c820191505b81811015610d3b578281556001016125fa565b81516001600160401b0381111561262657612626611af8565b61263a8161263484546120ac565b846125c7565b602080601f83116001811461266f57600084156126575750858301515b600019600386901b1c1916600185901b178555610d3b565b600085815260208120601f198616915b8281101561269e5788860151825594840194600190910190840161267f565b50858210156126bc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008160001904831182151516156126e6576126e661214b565b500290565b6000816126fa576126fa61214b565b506000190190565b818103818111156103f8576103f861214b565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d84f746f173a737e6816e4123648488df6b8e119ec4b4fc93237fc9c098d976b64736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c873146102b4578063d5391393146102c7578063d547741f146102ee578063e985e9c514610301578063f242432a1461033d578063f5298aca1461035057600080fd5b8063731133e9146102485780639010d07c1461025b57806391d1485414610286578063a217fddf14610299578063a22cb465146102a157600080fd5b80632eb2c2d6116100ff5780632eb2c2d6146101dc5780632f2ff15d146101ef57806336568abe146102025780634e1273f4146102155780636b20c4541461023557600080fd5b8062fdd58e1461013b57806301ffc9a7146101615780630e89341c146101845780631f7fdffa146101a4578063248a9ca3146101b9575b600080fd5b61014e610149366004611a1f565b610363565b6040519081526020015b60405180910390f35b61017461016f366004611a5f565b6103fe565b6040519015158152602001610158565b610197610192366004611a7c565b610409565b6040516101589190611ae5565b6101b76101b2366004611c41565b61049d565b005b61014e6101c7366004611a7c565b60009081526065602052604090206001015490565b6101b76101ea366004611cd9565b61051e565b6101b76101fd366004611d82565b61056a565b6101b7610210366004611d82565b610594565b610228610223366004611dae565b610612565b6040516101589190611eb3565b6101b7610243366004611ec6565b61073b565b6101b7610256366004611f39565b61077e565b61026e610269366004611f8d565b6107f9565b6040516001600160a01b039091168152602001610158565b610174610294366004611d82565b610818565b61014e600081565b6101b76102af366004611faf565b610843565b61014e6102c2366004611a7c565b61084e565b61014e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101b76102fc366004611d82565b610865565b61017461030f366004611feb565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205460ff1690565b6101b761034b366004612015565b61088a565b6101b761035e366004612079565b6108cf565b60006001600160a01b0383166103d35760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b50600081815260c9602090815260408083206001600160a01b03861684529091529020545b92915050565b60006103f882610a18565b606060cb8054610418906120ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610444906120ac565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b50505050509050919050565b6104c77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b61050c5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610a58565b50505050565b6001600160a01b03851633148061053a575061053a853361030f565b6105565760405162461bcd60e51b81526004016103ca906120e6565b6105638585858585610ba4565b5050505050565b60008281526065602052604090206001015461058581610d43565b61058f8383610d4d565b505050565b6001600160a01b03811633146106045760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016103ca565b61060e8282610d6f565b5050565b606081518351146106775760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016103ca565b600083516001600160401b0381111561069257610692611af8565b6040519080825280602002602001820160405280156106bb578160200160208202803683370190505b50905060005b8451811015610733576107068582815181106106df576106df612135565b60200260200101518583815181106106f9576106f9612135565b6020026020010151610363565b82828151811061071857610718612135565b602090810291909101015261072c81612161565b90506106c1565b509392505050565b6001600160a01b0383163314806107575750610757833361030f565b6107735760405162461bcd60e51b81526004016103ca906120e6565b61058f838383610d91565b6107a87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b6107ed5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610f1e565b60008281526097602052604081206108119083610ffa565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61060e338383611006565b60008181526097602052604081206103f8906110e6565b60008281526065602052604090206001015461088081610d43565b61058f8383610d6f565b6001600160a01b0385163314806108a657506108a6853361030f565b6108c25760405162461bcd60e51b81526004016103ca906120e6565b61056385858585856110f0565b6001600160a01b0383163314806108eb57506108eb833361030f565b6109075760405162461bcd60e51b81526004016103ca906120e6565b61058f83838361121e565b6001600160a01b03163b151590565b600054610100900460ff166109485760405162461bcd60e51b81526004016103ca9061217a565b565b600054610100900460ff166109715760405162461bcd60e51b81526004016103ca9061217a565b61097a81611325565b50565b6109878282610818565b61060e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556109bf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610811836001600160a01b038416611355565b60006001600160e01b03198216636cdb3d1360e11b1480610a4957506001600160e01b031982166303a24d0760e21b145b806103f857506103f8826113a4565b6001600160a01b038416610a7e5760405162461bcd60e51b81526004016103ca906121c5565b8151835114610a9f5760405162461bcd60e51b81526004016103ca90612206565b3360005b8451811015610b3c57838181518110610abe57610abe612135565b602002602001015160c96000878481518110610adc57610adc612135565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254610b24919061224e565b90915550819050610b3481612161565b915050610aa3565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610b8d929190612261565b60405180910390a4610563816000878787876113c9565b8151835114610bc55760405162461bcd60e51b81526004016103ca90612206565b6001600160a01b038416610beb5760405162461bcd60e51b81526004016103ca9061228f565b3360005b8451811015610cd5576000858281518110610c0c57610c0c612135565b602002602001015190506000858381518110610c2a57610c2a612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038e168352909352919091205490915081811015610c7b5760405162461bcd60e51b81526004016103ca906122d4565b600083815260c9602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290610cba90849061224e565b9250508190555050505080610cce90612161565b9050610bef565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d25929190612261565b60405180910390a4610d3b8187878787876113c9565b505050505050565b61097a8133611524565b610d57828261097d565b600082815260976020526040902061058f9082610a03565b610d798282611588565b600082815260976020526040902061058f90826115ef565b6001600160a01b038316610db75760405162461bcd60e51b81526004016103ca9061231e565b8051825114610dd85760405162461bcd60e51b81526004016103ca90612206565b604080516020810190915260009081905233905b8351811015610eb1576000848281518110610e0957610e09612135565b602002602001015190506000848381518110610e2757610e27612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038c168352909352919091205490915081811015610e785760405162461bcd60e51b81526004016103ca90612361565b600092835260c9602090815260408085206001600160a01b038b1686529091529092209103905580610ea981612161565b915050610dec565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610f02929190612261565b60405180910390a4604080516020810190915260009052610518565b6001600160a01b038416610f445760405162461bcd60e51b81526004016103ca906121c5565b336000610f5085611604565b90506000610f5d85611604565b9050600086815260c9602090815260408083206001600160a01b038b16845290915281208054879290610f9190849061224e565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610ff18360008989898961164f565b50505050505050565b6000610811838361170a565b816001600160a01b0316836001600160a01b0316036110795760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016103ca565b6001600160a01b03838116600081815260ca6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006103f8825490565b6001600160a01b0384166111165760405162461bcd60e51b81526004016103ca9061228f565b33600061112285611604565b9050600061112f85611604565b9050600086815260c9602090815260408083206001600160a01b038c168452909152902054858110156111745760405162461bcd60e51b81526004016103ca906122d4565b600087815260c9602090815260408083206001600160a01b038d8116855292528083208985039055908a168252812080548892906111b390849061224e565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611213848a8a8a8a8a61164f565b505050505050505050565b6001600160a01b0383166112445760405162461bcd60e51b81526004016103ca9061231e565b33600061125084611604565b9050600061125d84611604565b604080516020808201835260009182905288825260c981528282206001600160a01b038b16835290522054909150848110156112ab5760405162461bcd60e51b81526004016103ca90612361565b600086815260c9602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4604080516020810190915260009052610ff1565b600054610100900460ff1661134c5760405162461bcd60e51b81526004016103ca9061217a565b61097a81611734565b600081815260018301602052604081205461139c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103f8565b5060006103f8565b60006001600160e01b03198216635a05180f60e01b14806103f857506103f882611740565b6001600160a01b0384163b15610d3b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061140d90899089908890889088906004016123a5565b6020604051808303816000875af1925050508015611448575060408051601f3d908101601f1916820190925261144591810190612403565b60015b6114f457611454612420565b806308c379a00361148d575061146861243c565b80611473575061148f565b8060405162461bcd60e51b81526004016103ca9190611ae5565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016103ca565b6001600160e01b0319811663bc197c8160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b61152e8282610818565b61060e57611546816001600160a01b03166014611775565b611551836020611775565b60405160200161156292919061250d565b60408051601f198184030181529082905262461bcd60e51b82526103ca91600401611ae5565b6115928282610818565b1561060e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610811836001600160a01b038416611910565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061163e5761163e612135565b602090810291909101015292915050565b6001600160a01b0384163b15610d3b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906116939089908990889088908890600401612582565b6020604051808303816000875af19250505080156116ce575060408051601f3d908101601f191682019092526116cb91810190612403565b60015b6116da57611454612420565b6001600160e01b0319811663f23a6e6160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b600082600001828154811061172157611721612135565b9060005260206000200154905092915050565b60cb61060e828261260d565b60006001600160e01b03198216637965db0b60e01b14806103f857506301ffc9a760e01b6001600160e01b03198316146103f8565b606060006117848360026126cc565b61178f90600261224e565b6001600160401b038111156117a6576117a6611af8565b6040519080825280601f01601f1916602001820160405280156117d0576020820181803683370190505b509050600360fc1b816000815181106117eb576117eb612135565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061181a5761181a612135565b60200101906001600160f81b031916908160001a905350600061183e8460026126cc565b61184990600161224e565b90505b60018111156118c1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061187d5761187d612135565b1a60f81b82828151811061189357611893612135565b60200101906001600160f81b031916908160001a90535060049490941c936118ba816126eb565b905061184c565b5083156108115760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016103ca565b600081815260018301602052604081205480156119f9576000611934600183612702565b855490915060009061194890600190612702565b90508181146119ad57600086600001828154811061196857611968612135565b906000526020600020015490508087600001848154811061198b5761198b612135565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119be576119be612715565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103f8565b60009150506103f8565b80356001600160a01b0381168114611a1a57600080fd5b919050565b60008060408385031215611a3257600080fd5b611a3b83611a03565b946020939093013593505050565b6001600160e01b03198116811461097a57600080fd5b600060208284031215611a7157600080fd5b813561081181611a49565b600060208284031215611a8e57600080fd5b5035919050565b60005b83811015611ab0578181015183820152602001611a98565b50506000910152565b60008151808452611ad1816020860160208601611a95565b601f01601f19169290920160200192915050565b6020815260006108116020830184611ab9565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715611b3357611b33611af8565b6040525050565b60006001600160401b03821115611b5357611b53611af8565b5060051b60200190565b600082601f830112611b6e57600080fd5b81356020611b7b82611b3a565b604051611b888282611b0e565b83815260059390931b8501820192828101915086841115611ba857600080fd5b8286015b84811015611bc35780358352918301918301611bac565b509695505050505050565b600082601f830112611bdf57600080fd5b81356001600160401b03811115611bf857611bf8611af8565b604051611c0f601f8301601f191660200182611b0e565b818152846020838601011115611c2457600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611c5757600080fd5b611c6085611a03565b935060208501356001600160401b0380821115611c7c57600080fd5b611c8888838901611b5d565b94506040870135915080821115611c9e57600080fd5b611caa88838901611b5d565b93506060870135915080821115611cc057600080fd5b50611ccd87828801611bce565b91505092959194509250565b600080600080600060a08688031215611cf157600080fd5b611cfa86611a03565b9450611d0860208701611a03565b935060408601356001600160401b0380821115611d2457600080fd5b611d3089838a01611b5d565b94506060880135915080821115611d4657600080fd5b611d5289838a01611b5d565b93506080880135915080821115611d6857600080fd5b50611d7588828901611bce565b9150509295509295909350565b60008060408385031215611d9557600080fd5b82359150611da560208401611a03565b90509250929050565b60008060408385031215611dc157600080fd5b82356001600160401b0380821115611dd857600080fd5b818501915085601f830112611dec57600080fd5b81356020611df982611b3a565b604051611e068282611b0e565b83815260059390931b8501820192828101915089841115611e2657600080fd5b948201945b83861015611e4b57611e3c86611a03565b82529482019490820190611e2b565b96505086013592505080821115611e6157600080fd5b50611e6e85828601611b5d565b9150509250929050565b600081518084526020808501945080840160005b83811015611ea857815187529582019590820190600101611e8c565b509495945050505050565b6020815260006108116020830184611e78565b600080600060608486031215611edb57600080fd5b611ee484611a03565b925060208401356001600160401b0380821115611f0057600080fd5b611f0c87838801611b5d565b93506040860135915080821115611f2257600080fd5b50611f2f86828701611b5d565b9150509250925092565b60008060008060808587031215611f4f57600080fd5b611f5885611a03565b9350602085013592506040850135915060608501356001600160401b03811115611f8157600080fd5b611ccd87828801611bce565b60008060408385031215611fa057600080fd5b50508035926020909101359150565b60008060408385031215611fc257600080fd5b611fcb83611a03565b915060208301358015158114611fe057600080fd5b809150509250929050565b60008060408385031215611ffe57600080fd5b61200783611a03565b9150611da560208401611a03565b600080600080600060a0868803121561202d57600080fd5b61203686611a03565b945061204460208701611a03565b9350604086013592506060860135915060808601356001600160401b0381111561206d57600080fd5b611d7588828901611bce565b60008060006060848603121561208e57600080fd5b61209784611a03565b95602085013595506040909401359392505050565b600181811c908216806120c057607f821691505b6020821081036120e057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602f908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526e195c881b9bdc88185c1c1c9bdd9959608a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016121735761217361214b565b5060010190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b808201808211156103f8576103f861214b565b6040815260006122746040830185611e78565b82810360208401526122868185611e78565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526023908201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526024908201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604082015263616e636560e01b606082015260800190565b6001600160a01b0386811682528516602082015260a0604082018190526000906123d190830186611e78565b82810360608401526123e38186611e78565b905082810360808401526123f78185611ab9565b98975050505050505050565b60006020828403121561241557600080fd5b815161081181611a49565b600060033d11156124395760046000803e5060005160e01c5b90565b600060443d101561244a5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561247957505050505090565b82850191508151818111156124915750505050505090565b843d87010160208285010111156124ab5750505050505090565b6124ba60208286010187611b0e565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612545816017850160208801611a95565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612576816028840160208801611a95565b01602801949350505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906125bc90830184611ab9565b979650505050505050565b601f82111561058f57600081815260208120601f850160051c810160208610156125ee5750805b601f850160051c820191505b81811015610d3b578281556001016125fa565b81516001600160401b0381111561262657612626611af8565b61263a8161263484546120ac565b846125c7565b602080601f83116001811461266f57600084156126575750858301515b600019600386901b1c1916600185901b178555610d3b565b600085815260208120601f198616915b8281101561269e5788860151825594840194600190910190840161267f565b50858210156126bc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008160001904831182151516156126e6576126e661214b565b500290565b6000816126fa576126fa61214b565b506000190190565b818103818111156103f8576103f861214b565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d84f746f173a737e6816e4123648488df6b8e119ec4b4fc93237fc9c098d976b64736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.meta.json b/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.meta.json new file mode 100644 index 000000000..c3db0b28a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC1155OnChain.meta.json @@ -0,0 +1,410 @@ +{ + "name": "ERC1155OnChain", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.dbg.json b/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.json b/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.json new file mode 100644 index 000000000..09121f5a3 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.json @@ -0,0 +1,619 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ERC20OnChain", + "sourceName": "contracts/schain/tokens/ERC20OnChain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "contractName", + "type": "string" + }, + { + "internalType": "string", + "name": "contractSymbol", + "type": "string" + } + ], + "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": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "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": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "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": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b5060405162001ed438038062001ed48339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b620007211760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b620007301760201c565b6200013e83836200024660201b620007591760201c565b62000153620001e860201b620007301760201c565b6200016e60008051602062001eb483398151915280620002b2565b6200018960008051602062001eb483398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60cc62000373838262000698565b5060cd62000382828262000698565b505050565b6200039e8282620003c560201b6200078a1760201c565b6000828152609760209081526040909120620003829183906200081062000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61172080620007746000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d7146102ef578063a9059cbb14610302578063ca15c87314610315578063d539139314610328578063d547741f1461034f578063dd62ed3e1461036257600080fd5b806370a082311461026557806379cc67901461028e5780639010d07c146102a157806391d14854146102cc57806395d89b41146102df578063a217fddf146102e757600080fd5b80632f2ff15d116101155780632f2ff15d146101f5578063313ce5671461020a57806336568abe14610219578063395093511461022c57806340c10f191461023f57806342966c681461025257600080fd5b806301ffc9a71461015d57806306fdde0314610185578063095ea7b31461019a57806318160ddd146101ad57806323b872dd146101bf578063248a9ca3146101d2575b600080fd5b61017061016b36600461127f565b610375565b60405190151581526020015b60405180910390f35b61018d6103a0565b60405161017c91906112cd565b6101706101a836600461131c565b610432565b60cb545b60405190815260200161017c565b6101706101cd366004611346565b61044a565b6101b16101e0366004611382565b60009081526065602052604090206001015490565b61020861020336600461139b565b61046e565b005b6040516012815260200161017c565b61020861022736600461139b565b610498565b61017061023a36600461131c565b61051b565b61020861024d36600461131c565b61053d565b610208610260366004611382565b6105b6565b6101b16102733660046113c7565b6001600160a01b0316600090815260c9602052604090205490565b61020861029c36600461131c565b6105c3565b6102b46102af3660046113e2565b6105d8565b6040516001600160a01b03909116815260200161017c565b6101706102da36600461139b565b6105f7565b61018d610622565b6101b1600081565b6101706102fd36600461131c565b610631565b61017061031036600461131c565b6106ac565b6101b1610323366004611382565b6106ba565b6101b17f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61020861035d36600461139b565b6106d1565b6101b1610370366004611404565b6106f6565b60006001600160e01b03198216635a05180f60e01b148061039a575061039a82610825565b92915050565b606060cc80546103af9061142e565b80601f01602080910402602001604051908101604052809291908181526020018280546103db9061142e565b80156104285780601f106103fd57610100808354040283529160200191610428565b820191906000526020600020905b81548152906001019060200180831161040b57829003601f168201915b5050505050905090565b60003361044081858561085a565b5060019392505050565b60003361045885828561097e565b6104638585856109f8565b506001949350505050565b60008281526065602052604090206001015461048981610bc6565b6104938383610bd0565b505050565b6001600160a01b038116331461050d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105178282610bf2565b5050565b60003361044081858561052e83836106f6565b610538919061147e565b61085a565b6105677f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336105f7565b6105ac5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610504565b6105178282610c14565b6105c03382610cf3565b50565b6105ce82338361097e565b6105178282610cf3565b60008281526097602052604081206105f09083610e41565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd80546103af9061142e565b6000338161063f82866106f6565b90508381101561069f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610504565b610463828686840361085a565b6000336104408185856109f8565b600081815260976020526040812061039a90610e4d565b6000828152606560205260409020600101546106ec81610bc6565b6104938383610bf2565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6001600160a01b03163b151590565b600054610100900460ff166107575760405162461bcd60e51b815260040161050490611491565b565b600054610100900460ff166107805760405162461bcd60e51b815260040161050490611491565b6105178282610e57565b61079482826105f7565b6105175760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107cc3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006105f0836001600160a01b038416610e97565b60006001600160e01b03198216637965db0b60e01b148061039a57506301ffc9a760e01b6001600160e01b031983161461039a565b6001600160a01b0383166108bc5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610504565b6001600160a01b03821661091d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610504565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061098a84846106f6565b905060001981146109f257818110156109e55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610504565b6109f2848484840361085a565b50505050565b6001600160a01b038316610a5c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610504565b6001600160a01b038216610abe5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610504565b6001600160a01b038316600090815260c9602052604090205481811015610b365760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610504565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610b6d90849061147e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610bb991815260200190565b60405180910390a36109f2565b6105c08133610ee6565b610bda828261078a565b60008281526097602052604090206104939082610810565b610bfc8282610f4a565b60008281526097602052604090206104939082610fb1565b6001600160a01b038216610c6a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610504565b8060cb6000828254610c7c919061147e565b90915550506001600160a01b038216600090815260c9602052604081208054839290610ca990849061147e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610d535760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610504565b6001600160a01b038216600090815260c9602052604090205481811015610dc75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610504565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610df69084906114dc565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006105f08383610fc6565b600061039a825490565b600054610100900460ff16610e7e5760405162461bcd60e51b815260040161050490611491565b60cc610e8a8382611553565b5060cd6104938282611553565b6000818152600183016020526040812054610ede5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561039a565b50600061039a565b610ef082826105f7565b61051757610f08816001600160a01b03166014610ff0565b610f13836020610ff0565b604051602001610f24929190611613565b60408051601f198184030181529082905262461bcd60e51b8252610504916004016112cd565b610f5482826105f7565b156105175760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006105f0836001600160a01b03841661118c565b6000826000018281548110610fdd57610fdd611688565b9060005260206000200154905092915050565b60606000610fff83600261169e565b61100a90600261147e565b67ffffffffffffffff811115611022576110226114ef565b6040519080825280601f01601f19166020018201604052801561104c576020820181803683370190505b509050600360fc1b8160008151811061106757611067611688565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061109657611096611688565b60200101906001600160f81b031916908160001a90535060006110ba84600261169e565b6110c590600161147e565b90505b600181111561113d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110f9576110f9611688565b1a60f81b82828151811061110f5761110f611688565b60200101906001600160f81b031916908160001a90535060049490941c93611136816116bd565b90506110c8565b5083156105f05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610504565b600081815260018301602052604081205480156112755760006111b06001836114dc565b85549091506000906111c4906001906114dc565b90508181146112295760008660000182815481106111e4576111e4611688565b906000526020600020015490508087600001848154811061120757611207611688565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061123a5761123a6116d4565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061039a565b600091505061039a565b60006020828403121561129157600080fd5b81356001600160e01b0319811681146105f057600080fd5b60005b838110156112c45781810151838201526020016112ac565b50506000910152565b60208152600082518060208401526112ec8160408501602087016112a9565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461131757600080fd5b919050565b6000806040838503121561132f57600080fd5b61133883611300565b946020939093013593505050565b60008060006060848603121561135b57600080fd5b61136484611300565b925061137260208501611300565b9150604084013590509250925092565b60006020828403121561139457600080fd5b5035919050565b600080604083850312156113ae57600080fd5b823591506113be60208401611300565b90509250929050565b6000602082840312156113d957600080fd5b6105f082611300565b600080604083850312156113f557600080fd5b50508035926020909101359150565b6000806040838503121561141757600080fd5b61142083611300565b91506113be60208401611300565b600181811c9082168061144257607f821691505b60208210810361146257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561039a5761039a611468565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8181038181111561039a5761039a611468565b634e487b7160e01b600052604160045260246000fd5b601f82111561049357600081815260208120601f850160051c8101602086101561152c5750805b601f850160051c820191505b8181101561154b57828155600101611538565b505050505050565b815167ffffffffffffffff81111561156d5761156d6114ef565b6115818161157b845461142e565b84611505565b602080601f8311600181146115b6576000841561159e5750858301515b600019600386901b1c1916600185901b17855561154b565b600085815260208120601f198616915b828110156115e5578886015182559484019460019091019084016115c6565b50858210156116035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161164b8160178501602088016112a9565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161167c8160288401602088016112a9565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156116b8576116b8611468565b500290565b6000816116cc576116cc611468565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212202f9e9a6091230d31a1843f8d7bfacf836c46ab8210847934d487741528853dc964736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101585760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d7146102ef578063a9059cbb14610302578063ca15c87314610315578063d539139314610328578063d547741f1461034f578063dd62ed3e1461036257600080fd5b806370a082311461026557806379cc67901461028e5780639010d07c146102a157806391d14854146102cc57806395d89b41146102df578063a217fddf146102e757600080fd5b80632f2ff15d116101155780632f2ff15d146101f5578063313ce5671461020a57806336568abe14610219578063395093511461022c57806340c10f191461023f57806342966c681461025257600080fd5b806301ffc9a71461015d57806306fdde0314610185578063095ea7b31461019a57806318160ddd146101ad57806323b872dd146101bf578063248a9ca3146101d2575b600080fd5b61017061016b36600461127f565b610375565b60405190151581526020015b60405180910390f35b61018d6103a0565b60405161017c91906112cd565b6101706101a836600461131c565b610432565b60cb545b60405190815260200161017c565b6101706101cd366004611346565b61044a565b6101b16101e0366004611382565b60009081526065602052604090206001015490565b61020861020336600461139b565b61046e565b005b6040516012815260200161017c565b61020861022736600461139b565b610498565b61017061023a36600461131c565b61051b565b61020861024d36600461131c565b61053d565b610208610260366004611382565b6105b6565b6101b16102733660046113c7565b6001600160a01b0316600090815260c9602052604090205490565b61020861029c36600461131c565b6105c3565b6102b46102af3660046113e2565b6105d8565b6040516001600160a01b03909116815260200161017c565b6101706102da36600461139b565b6105f7565b61018d610622565b6101b1600081565b6101706102fd36600461131c565b610631565b61017061031036600461131c565b6106ac565b6101b1610323366004611382565b6106ba565b6101b17f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61020861035d36600461139b565b6106d1565b6101b1610370366004611404565b6106f6565b60006001600160e01b03198216635a05180f60e01b148061039a575061039a82610825565b92915050565b606060cc80546103af9061142e565b80601f01602080910402602001604051908101604052809291908181526020018280546103db9061142e565b80156104285780601f106103fd57610100808354040283529160200191610428565b820191906000526020600020905b81548152906001019060200180831161040b57829003601f168201915b5050505050905090565b60003361044081858561085a565b5060019392505050565b60003361045885828561097e565b6104638585856109f8565b506001949350505050565b60008281526065602052604090206001015461048981610bc6565b6104938383610bd0565b505050565b6001600160a01b038116331461050d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105178282610bf2565b5050565b60003361044081858561052e83836106f6565b610538919061147e565b61085a565b6105677f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336105f7565b6105ac5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610504565b6105178282610c14565b6105c03382610cf3565b50565b6105ce82338361097e565b6105178282610cf3565b60008281526097602052604081206105f09083610e41565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd80546103af9061142e565b6000338161063f82866106f6565b90508381101561069f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610504565b610463828686840361085a565b6000336104408185856109f8565b600081815260976020526040812061039a90610e4d565b6000828152606560205260409020600101546106ec81610bc6565b6104938383610bf2565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6001600160a01b03163b151590565b600054610100900460ff166107575760405162461bcd60e51b815260040161050490611491565b565b600054610100900460ff166107805760405162461bcd60e51b815260040161050490611491565b6105178282610e57565b61079482826105f7565b6105175760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107cc3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006105f0836001600160a01b038416610e97565b60006001600160e01b03198216637965db0b60e01b148061039a57506301ffc9a760e01b6001600160e01b031983161461039a565b6001600160a01b0383166108bc5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610504565b6001600160a01b03821661091d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610504565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061098a84846106f6565b905060001981146109f257818110156109e55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610504565b6109f2848484840361085a565b50505050565b6001600160a01b038316610a5c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610504565b6001600160a01b038216610abe5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610504565b6001600160a01b038316600090815260c9602052604090205481811015610b365760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610504565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610b6d90849061147e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610bb991815260200190565b60405180910390a36109f2565b6105c08133610ee6565b610bda828261078a565b60008281526097602052604090206104939082610810565b610bfc8282610f4a565b60008281526097602052604090206104939082610fb1565b6001600160a01b038216610c6a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610504565b8060cb6000828254610c7c919061147e565b90915550506001600160a01b038216600090815260c9602052604081208054839290610ca990849061147e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610d535760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610504565b6001600160a01b038216600090815260c9602052604090205481811015610dc75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610504565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610df69084906114dc565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006105f08383610fc6565b600061039a825490565b600054610100900460ff16610e7e5760405162461bcd60e51b815260040161050490611491565b60cc610e8a8382611553565b5060cd6104938282611553565b6000818152600183016020526040812054610ede5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561039a565b50600061039a565b610ef082826105f7565b61051757610f08816001600160a01b03166014610ff0565b610f13836020610ff0565b604051602001610f24929190611613565b60408051601f198184030181529082905262461bcd60e51b8252610504916004016112cd565b610f5482826105f7565b156105175760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006105f0836001600160a01b03841661118c565b6000826000018281548110610fdd57610fdd611688565b9060005260206000200154905092915050565b60606000610fff83600261169e565b61100a90600261147e565b67ffffffffffffffff811115611022576110226114ef565b6040519080825280601f01601f19166020018201604052801561104c576020820181803683370190505b509050600360fc1b8160008151811061106757611067611688565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061109657611096611688565b60200101906001600160f81b031916908160001a90535060006110ba84600261169e565b6110c590600161147e565b90505b600181111561113d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110f9576110f9611688565b1a60f81b82828151811061110f5761110f611688565b60200101906001600160f81b031916908160001a90535060049490941c93611136816116bd565b90506110c8565b5083156105f05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610504565b600081815260018301602052604081205480156112755760006111b06001836114dc565b85549091506000906111c4906001906114dc565b90508181146112295760008660000182815481106111e4576111e4611688565b906000526020600020015490508087600001848154811061120757611207611688565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061123a5761123a6116d4565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061039a565b600091505061039a565b60006020828403121561129157600080fd5b81356001600160e01b0319811681146105f057600080fd5b60005b838110156112c45781810151838201526020016112ac565b50506000910152565b60208152600082518060208401526112ec8160408501602087016112a9565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461131757600080fd5b919050565b6000806040838503121561132f57600080fd5b61133883611300565b946020939093013593505050565b60008060006060848603121561135b57600080fd5b61136484611300565b925061137260208501611300565b9150604084013590509250925092565b60006020828403121561139457600080fd5b5035919050565b600080604083850312156113ae57600080fd5b823591506113be60208401611300565b90509250929050565b6000602082840312156113d957600080fd5b6105f082611300565b600080604083850312156113f557600080fd5b50508035926020909101359150565b6000806040838503121561141757600080fd5b61142083611300565b91506113be60208401611300565b600181811c9082168061144257607f821691505b60208210810361146257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561039a5761039a611468565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8181038181111561039a5761039a611468565b634e487b7160e01b600052604160045260246000fd5b601f82111561049357600081815260208120601f850160051c8101602086101561152c5750805b601f850160051c820191505b8181101561154b57828155600101611538565b505050505050565b815167ffffffffffffffff81111561156d5761156d6114ef565b6115818161157b845461142e565b84611505565b602080601f8311600181146115b6576000841561159e5750858301515b600019600386901b1c1916600185901b17855561154b565b600085815260208120601f198616915b828110156115e5578886015182559484019460019091019084016115c6565b50858210156116035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161164b8160178501602088016112a9565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161167c8160288401602088016112a9565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156116b8576116b8611468565b500290565b6000816116cc576116cc611468565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212202f9e9a6091230d31a1843f8d7bfacf836c46ab8210847934d487741528853dc964736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.meta.json b/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.meta.json new file mode 100644 index 000000000..a2ceecac9 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC20OnChain.meta.json @@ -0,0 +1,410 @@ +{ + "name": "ERC20OnChain", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.dbg.json b/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.json b/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.json new file mode 100644 index 000000000..73878cbba --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.json @@ -0,0 +1,666 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ERC721OnChain", + "sourceName": "contracts/schain/tokens/ERC721OnChain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "contractName", + "type": "string" + }, + { + "internalType": "string", + "name": "contractSymbol", + "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": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "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": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "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": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "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": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "tokenUri", + "type": "string" + } + ], + "name": "setTokenURI", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "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": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "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" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b5060405162002a5538038062002a558339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b62000a3c1760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b62000a4b1760201c565b6200013e83836200024660201b62000a741760201c565b62000153620001e860201b62000a4b1760201c565b6200016e60008051602062002a3583398151915280620002b2565b6200018960008051602062002a3583398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60c962000373838262000698565b5060ca62000382828262000698565b505050565b6200039e8282620003c560201b62000aa51760201c565b60008281526097602090815260409091206200038291839062000b2b62000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6122a180620007746000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.meta.json b/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.meta.json new file mode 100644 index 000000000..19bdc23b9 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ERC721OnChain.meta.json @@ -0,0 +1,410 @@ +{ + "name": "ERC721OnChain", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/EthErc20.dbg.json b/predeployed/src/ima_predeployed/artifacts/EthErc20.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/EthErc20.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/EthErc20.json b/predeployed/src/ima_predeployed/artifacts/EthErc20.json new file mode 100644 index 000000000..42f570d57 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/EthErc20.json @@ -0,0 +1,647 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "EthErc20", + "sourceName": "contracts/schain/tokens/EthErc20.sol", + "abi": [ + { + "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": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "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": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "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": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "forceBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": "address", + "name": "tokenManagerEthAddress", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "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": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b506119fd806100206000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806370a08231116100f9578063a9059cbb11610097578063d539139311610071578063d5391393146103b3578063d547741f146103da578063dd62ed3e146103ed578063e2d6f6341461040057600080fd5b8063a9059cbb1461037a578063c4d66de81461038d578063ca15c873146103a057600080fd5b806391d14854116100d357806391d148541461034457806395d89b4114610357578063a217fddf1461035f578063a457c2d71461036757600080fd5b806370a08231146102dd57806379cc6790146103065780639010d07c1461031957600080fd5b8063282c51f31161016657806336568abe1161014057806336568abe1461029157806339509351146102a457806340c10f19146102b757806342966c68146102ca57600080fd5b8063282c51f3146102465780632f2ff15d1461026d578063313ce5671461028257600080fd5b806301ffc9a7146101ae57806306fdde03146101d6578063095ea7b3146101eb57806318160ddd146101fe57806323b872dd14610210578063248a9ca314610223575b600080fd5b6101c16101bc36600461155c565b610413565b60405190151581526020015b60405180910390f35b6101de61043e565b6040516101cd91906115aa565b6101c16101f93660046115f9565b6104d0565b60cb545b6040519081526020016101cd565b6101c161021e366004611623565b6104e8565b61020261023136600461165f565b60009081526065602052604090206001015490565b6102027f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61028061027b366004611678565b61050c565b005b604051601281526020016101cd565b61028061029f366004611678565b610536565b6101c16102b23660046115f9565b6105b9565b6102806102c53660046115f9565b6105db565b6102806102d836600461165f565b61065b565b6102026102eb3660046116a4565b6001600160a01b0316600090815260c9602052604090205490565b6102806103143660046115f9565b610668565b61032c6103273660046116bf565b61067d565b6040516001600160a01b0390911681526020016101cd565b6101c1610352366004611678565b61069c565b6101de6106c7565b610202600081565b6101c16103753660046115f9565b6106d6565b6101c16103883660046115f9565b610751565b61028061039b3660046116a4565b61075f565b6102026103ae36600461165f565b610926565b6102027f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6102806103e8366004611678565b61093d565b6102026103fb3660046116e1565b610962565b61028061040e3660046115f9565b61098d565b60006001600160e01b03198216635a05180f60e01b1480610438575061043882610a03565b92915050565b606060cc805461044d9061170b565b80601f01602080910402602001604051908101604052809291908181526020018280546104799061170b565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b5050505050905090565b6000336104de818585610a38565b5060019392505050565b6000336104f6858285610b5c565b610501858585610bd6565b506001949350505050565b60008281526065602052604090206001015461052781610da4565b6105318383610dae565b505050565b6001600160a01b03811633146105ab5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105b58282610dd0565b5050565b6000336104de8185856105cc8383610962565b6105d6919061175b565b610a38565b6106057f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63361069c565b6106515760405162461bcd60e51b815260206004820152601760248201527f4d494e54455220726f6c6520697320726571756972656400000000000000000060448201526064016105a2565b6105b58282610df2565b6106653382610ed1565b50565b610673823383610b5c565b6105b58282610ed1565b6000828152609760205260408120610695908361101f565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd805461044d9061170b565b600033816106e48286610962565b9050838110156107445760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016105a2565b6105018286868403610a38565b6000336104de818585610bd6565b600054610100900460ff161580801561077f5750600054600160ff909116105b806107995750303b158015610799575060005460ff166001145b6107fc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105a2565b6000805460ff19166001179055801561081f576000805461ff0019166101001790555b61082761102b565b61087660405180604001604052806011815260200170455243323020457468657220436c6f6e6560781b815250604051806040016040528060048152602001634554484360e01b815250611054565b61087e61102b565b610889600033611085565b6108b37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a683611085565b6108dd7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84883611085565b80156105b5576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60008181526097602052604081206104389061108f565b60008281526065602052604090206001015461095881610da4565b6105318383610dd0565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6109b77f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483361069c565b6106735760405162461bcd60e51b815260206004820152601760248201527f4255524e455220726f6c6520697320726571756972656400000000000000000060448201526064016105a2565b60006001600160e01b03198216637965db0b60e01b148061043857506301ffc9a760e01b6001600160e01b0319831614610438565b6001600160a01b038316610a9a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016105a2565b6001600160a01b038216610afb5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016105a2565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000610b688484610962565b90506000198114610bd05781811015610bc35760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105a2565b610bd08484848403610a38565b50505050565b6001600160a01b038316610c3a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016105a2565b6001600160a01b038216610c9c5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016105a2565b6001600160a01b038316600090815260c9602052604090205481811015610d145760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016105a2565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610d4b90849061175b565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d9791815260200190565b60405180910390a3610bd0565b6106658133611099565b610db882826110fd565b60008281526097602052604090206105319082611183565b610dda8282611198565b600082815260976020526040902061053190826111ff565b6001600160a01b038216610e485760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105a2565b8060cb6000828254610e5a919061175b565b90915550506001600160a01b038216600090815260c9602052604081208054839290610e8790849061175b565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610f315760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016105a2565b6001600160a01b038216600090815260c9602052604090205481811015610fa55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016105a2565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610fd490849061176e565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006106958383611214565b600054610100900460ff166110525760405162461bcd60e51b81526004016105a290611781565b565b600054610100900460ff1661107b5760405162461bcd60e51b81526004016105a290611781565b6105b5828261123e565b6105b58282610dae565b6000610438825490565b6110a3828261069c565b6105b5576110bb816001600160a01b0316601461127e565b6110c683602061127e565b6040516020016110d79291906117cc565b60408051601f198184030181529082905262461bcd60e51b82526105a2916004016115aa565b611107828261069c565b6105b55760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561113f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610695836001600160a01b03841661141a565b6111a2828261069c565b156105b55760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610695836001600160a01b038416611469565b600082600001828154811061122b5761122b611841565b9060005260206000200154905092915050565b600054610100900460ff166112655760405162461bcd60e51b81526004016105a290611781565b60cc61127183826118bb565b5060cd61053182826118bb565b6060600061128d83600261197b565b61129890600261175b565b67ffffffffffffffff8111156112b0576112b0611857565b6040519080825280601f01601f1916602001820160405280156112da576020820181803683370190505b509050600360fc1b816000815181106112f5576112f5611841565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061132457611324611841565b60200101906001600160f81b031916908160001a905350600061134884600261197b565b61135390600161175b565b90505b60018111156113cb576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061138757611387611841565b1a60f81b82828151811061139d5761139d611841565b60200101906001600160f81b031916908160001a90535060049490941c936113c48161199a565b9050611356565b5083156106955760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016105a2565b600081815260018301602052604081205461146157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610438565b506000610438565b6000818152600183016020526040812054801561155257600061148d60018361176e565b85549091506000906114a19060019061176e565b90508181146115065760008660000182815481106114c1576114c1611841565b90600052602060002001549050808760000184815481106114e4576114e4611841565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611517576115176119b1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610438565b6000915050610438565b60006020828403121561156e57600080fd5b81356001600160e01b03198116811461069557600080fd5b60005b838110156115a1578181015183820152602001611589565b50506000910152565b60208152600082518060208401526115c9816040850160208701611586565b601f01601f19169190910160400192915050565b80356001600160a01b03811681146115f457600080fd5b919050565b6000806040838503121561160c57600080fd5b611615836115dd565b946020939093013593505050565b60008060006060848603121561163857600080fd5b611641846115dd565b925061164f602085016115dd565b9150604084013590509250925092565b60006020828403121561167157600080fd5b5035919050565b6000806040838503121561168b57600080fd5b8235915061169b602084016115dd565b90509250929050565b6000602082840312156116b657600080fd5b610695826115dd565b600080604083850312156116d257600080fd5b50508035926020909101359150565b600080604083850312156116f457600080fd5b6116fd836115dd565b915061169b602084016115dd565b600181811c9082168061171f57607f821691505b60208210810361173f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561043857610438611745565b8181038181111561043857610438611745565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611804816017850160208801611586565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611835816028840160208801611586565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f82111561053157600081815260208120601f850160051c810160208610156118945750805b601f850160051c820191505b818110156118b3578281556001016118a0565b505050505050565b815167ffffffffffffffff8111156118d5576118d5611857565b6118e9816118e3845461170b565b8461186d565b602080601f83116001811461191e57600084156119065750858301515b600019600386901b1c1916600185901b1785556118b3565b600085815260208120601f198616915b8281101561194d5788860151825594840194600190910190840161192e565b508582101561196b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081600019048311821515161561199557611995611745565b500290565b6000816119a9576119a9611745565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212204a8c446125b4466580bc5f64979dc7a7facca59521b4d0ebea6ecd938f789eda64736f6c63430008100033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806370a08231116100f9578063a9059cbb11610097578063d539139311610071578063d5391393146103b3578063d547741f146103da578063dd62ed3e146103ed578063e2d6f6341461040057600080fd5b8063a9059cbb1461037a578063c4d66de81461038d578063ca15c873146103a057600080fd5b806391d14854116100d357806391d148541461034457806395d89b4114610357578063a217fddf1461035f578063a457c2d71461036757600080fd5b806370a08231146102dd57806379cc6790146103065780639010d07c1461031957600080fd5b8063282c51f31161016657806336568abe1161014057806336568abe1461029157806339509351146102a457806340c10f19146102b757806342966c68146102ca57600080fd5b8063282c51f3146102465780632f2ff15d1461026d578063313ce5671461028257600080fd5b806301ffc9a7146101ae57806306fdde03146101d6578063095ea7b3146101eb57806318160ddd146101fe57806323b872dd14610210578063248a9ca314610223575b600080fd5b6101c16101bc36600461155c565b610413565b60405190151581526020015b60405180910390f35b6101de61043e565b6040516101cd91906115aa565b6101c16101f93660046115f9565b6104d0565b60cb545b6040519081526020016101cd565b6101c161021e366004611623565b6104e8565b61020261023136600461165f565b60009081526065602052604090206001015490565b6102027f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61028061027b366004611678565b61050c565b005b604051601281526020016101cd565b61028061029f366004611678565b610536565b6101c16102b23660046115f9565b6105b9565b6102806102c53660046115f9565b6105db565b6102806102d836600461165f565b61065b565b6102026102eb3660046116a4565b6001600160a01b0316600090815260c9602052604090205490565b6102806103143660046115f9565b610668565b61032c6103273660046116bf565b61067d565b6040516001600160a01b0390911681526020016101cd565b6101c1610352366004611678565b61069c565b6101de6106c7565b610202600081565b6101c16103753660046115f9565b6106d6565b6101c16103883660046115f9565b610751565b61028061039b3660046116a4565b61075f565b6102026103ae36600461165f565b610926565b6102027f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6102806103e8366004611678565b61093d565b6102026103fb3660046116e1565b610962565b61028061040e3660046115f9565b61098d565b60006001600160e01b03198216635a05180f60e01b1480610438575061043882610a03565b92915050565b606060cc805461044d9061170b565b80601f01602080910402602001604051908101604052809291908181526020018280546104799061170b565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b5050505050905090565b6000336104de818585610a38565b5060019392505050565b6000336104f6858285610b5c565b610501858585610bd6565b506001949350505050565b60008281526065602052604090206001015461052781610da4565b6105318383610dae565b505050565b6001600160a01b03811633146105ab5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105b58282610dd0565b5050565b6000336104de8185856105cc8383610962565b6105d6919061175b565b610a38565b6106057f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63361069c565b6106515760405162461bcd60e51b815260206004820152601760248201527f4d494e54455220726f6c6520697320726571756972656400000000000000000060448201526064016105a2565b6105b58282610df2565b6106653382610ed1565b50565b610673823383610b5c565b6105b58282610ed1565b6000828152609760205260408120610695908361101f565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd805461044d9061170b565b600033816106e48286610962565b9050838110156107445760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016105a2565b6105018286868403610a38565b6000336104de818585610bd6565b600054610100900460ff161580801561077f5750600054600160ff909116105b806107995750303b158015610799575060005460ff166001145b6107fc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105a2565b6000805460ff19166001179055801561081f576000805461ff0019166101001790555b61082761102b565b61087660405180604001604052806011815260200170455243323020457468657220436c6f6e6560781b815250604051806040016040528060048152602001634554484360e01b815250611054565b61087e61102b565b610889600033611085565b6108b37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a683611085565b6108dd7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84883611085565b80156105b5576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60008181526097602052604081206104389061108f565b60008281526065602052604090206001015461095881610da4565b6105318383610dd0565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6109b77f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483361069c565b6106735760405162461bcd60e51b815260206004820152601760248201527f4255524e455220726f6c6520697320726571756972656400000000000000000060448201526064016105a2565b60006001600160e01b03198216637965db0b60e01b148061043857506301ffc9a760e01b6001600160e01b0319831614610438565b6001600160a01b038316610a9a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016105a2565b6001600160a01b038216610afb5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016105a2565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000610b688484610962565b90506000198114610bd05781811015610bc35760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105a2565b610bd08484848403610a38565b50505050565b6001600160a01b038316610c3a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016105a2565b6001600160a01b038216610c9c5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016105a2565b6001600160a01b038316600090815260c9602052604090205481811015610d145760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016105a2565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610d4b90849061175b565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d9791815260200190565b60405180910390a3610bd0565b6106658133611099565b610db882826110fd565b60008281526097602052604090206105319082611183565b610dda8282611198565b600082815260976020526040902061053190826111ff565b6001600160a01b038216610e485760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105a2565b8060cb6000828254610e5a919061175b565b90915550506001600160a01b038216600090815260c9602052604081208054839290610e8790849061175b565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610f315760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016105a2565b6001600160a01b038216600090815260c9602052604090205481811015610fa55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016105a2565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610fd490849061176e565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006106958383611214565b600054610100900460ff166110525760405162461bcd60e51b81526004016105a290611781565b565b600054610100900460ff1661107b5760405162461bcd60e51b81526004016105a290611781565b6105b5828261123e565b6105b58282610dae565b6000610438825490565b6110a3828261069c565b6105b5576110bb816001600160a01b0316601461127e565b6110c683602061127e565b6040516020016110d79291906117cc565b60408051601f198184030181529082905262461bcd60e51b82526105a2916004016115aa565b611107828261069c565b6105b55760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561113f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610695836001600160a01b03841661141a565b6111a2828261069c565b156105b55760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610695836001600160a01b038416611469565b600082600001828154811061122b5761122b611841565b9060005260206000200154905092915050565b600054610100900460ff166112655760405162461bcd60e51b81526004016105a290611781565b60cc61127183826118bb565b5060cd61053182826118bb565b6060600061128d83600261197b565b61129890600261175b565b67ffffffffffffffff8111156112b0576112b0611857565b6040519080825280601f01601f1916602001820160405280156112da576020820181803683370190505b509050600360fc1b816000815181106112f5576112f5611841565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061132457611324611841565b60200101906001600160f81b031916908160001a905350600061134884600261197b565b61135390600161175b565b90505b60018111156113cb576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061138757611387611841565b1a60f81b82828151811061139d5761139d611841565b60200101906001600160f81b031916908160001a90535060049490941c936113c48161199a565b9050611356565b5083156106955760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016105a2565b600081815260018301602052604081205461146157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610438565b506000610438565b6000818152600183016020526040812054801561155257600061148d60018361176e565b85549091506000906114a19060019061176e565b90508181146115065760008660000182815481106114c1576114c1611841565b90600052602060002001549050808760000184815481106114e4576114e4611841565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611517576115176119b1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610438565b6000915050610438565b60006020828403121561156e57600080fd5b81356001600160e01b03198116811461069557600080fd5b60005b838110156115a1578181015183820152602001611589565b50506000910152565b60208152600082518060208401526115c9816040850160208701611586565b601f01601f19169190910160400192915050565b80356001600160a01b03811681146115f457600080fd5b919050565b6000806040838503121561160c57600080fd5b611615836115dd565b946020939093013593505050565b60008060006060848603121561163857600080fd5b611641846115dd565b925061164f602085016115dd565b9150604084013590509250925092565b60006020828403121561167157600080fd5b5035919050565b6000806040838503121561168b57600080fd5b8235915061169b602084016115dd565b90509250929050565b6000602082840312156116b657600080fd5b610695826115dd565b600080604083850312156116d257600080fd5b50508035926020909101359150565b600080604083850312156116f457600080fd5b6116fd836115dd565b915061169b602084016115dd565b600181811c9082168061171f57607f821691505b60208210810361173f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561043857610438611745565b8181038181111561043857610438611745565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611804816017850160208801611586565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611835816028840160208801611586565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f82111561053157600081815260208120601f850160051c810160208610156118945750805b601f850160051c820191505b818110156118b3578281556001016118a0565b505050505050565b815167ffffffffffffffff8111156118d5576118d5611857565b6118e9816118e3845461170b565b8461186d565b602080601f83116001811461191e57600084156119065750858301515b600019600386901b1c1916600185901b1785556118b3565b600085815260208120601f198616915b8281101561194d5788860151825594840194600190910190840161192e565b508582101561196b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081600019048311821515161561199557611995611745565b500290565b6000816119a9576119a9611745565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212204a8c446125b4466580bc5f64979dc7a7facca59521b4d0ebea6ecd938f789eda64736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/EthErc20.meta.json b/predeployed/src/ima_predeployed/artifacts/EthErc20.meta.json new file mode 100644 index 000000000..4c60c0bb7 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/EthErc20.meta.json @@ -0,0 +1,410 @@ +{ + "name": "EthErc20", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/Fp2Operations.dbg.json b/predeployed/src/ima_predeployed/artifacts/Fp2Operations.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/Fp2Operations.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/Fp2Operations.json b/predeployed/src/ima_predeployed/artifacts/Fp2Operations.json new file mode 100644 index 000000000..2c3f6ab14 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/Fp2Operations.json @@ -0,0 +1,24 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "Fp2Operations", + "sourceName": "contracts/schain/bls/FieldOperations.sol", + "abi": [ + { + "inputs": [], + "name": "P", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60aa610024600b82828239805160001a607314601757fe5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c80638b8fbd92146038575b600080fd5b603e6050565b60408051918252519081900360200190f35b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478156fea264697066735822122005a640d392fc5f1ed84e8cfcb3f106269ba47e2bcf80fe41b37878441a2a89b964736f6c634300060c0033", + "deployedBytecode": "0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c80638b8fbd92146038575b600080fd5b603e6050565b60408051918252519081900360200190f35b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478156fea264697066735822122005a640d392fc5f1ed84e8cfcb3f106269ba47e2bcf80fe41b37878441a2a89b964736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/G1Operations.dbg.json b/predeployed/src/ima_predeployed/artifacts/G1Operations.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/G1Operations.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/G1Operations.json b/predeployed/src/ima_predeployed/artifacts/G1Operations.json new file mode 100644 index 000000000..c6c1a6b31 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/G1Operations.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "G1Operations", + "sourceName": "contracts/schain/bls/FieldOperations.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d2c7b848dbfe44c933cb9e4077309629271826944e59921445c8d65473cd143764736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d2c7b848dbfe44c933cb9e4077309629271826944e59921445c8d65473cd143764736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/G2Operations.dbg.json b/predeployed/src/ima_predeployed/artifacts/G2Operations.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/G2Operations.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/G2Operations.json b/predeployed/src/ima_predeployed/artifacts/G2Operations.json new file mode 100644 index 000000000..cd49226e3 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/G2Operations.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "G2Operations", + "sourceName": "contracts/schain/bls/FieldOperations.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122040e04307c36dd999e61c62d94b18263ca666c66ec90fcc123cb0d3e290e4fd3e64736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122040e04307c36dd999e61c62d94b18263ca666c66ec90fcc123cb0d3e290e4fd3e64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/IContractReceiverForSchain.dbg.json b/predeployed/src/ima_predeployed/artifacts/IContractReceiverForSchain.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/IContractReceiverForSchain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/IContractReceiverForSchain.json b/predeployed/src/ima_predeployed/artifacts/IContractReceiverForSchain.json new file mode 100644 index 000000000..3bea12cc7 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/IContractReceiverForSchain.json @@ -0,0 +1,40 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "IContractReceiverForSchain", + "sourceName": "contracts/schain/MessageProxyForSchain.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/KeyStorage.dbg.json b/predeployed/src/ima_predeployed/artifacts/KeyStorage.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/KeyStorage.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/KeyStorage.json b/predeployed/src/ima_predeployed/artifacts/KeyStorage.json new file mode 100644 index 000000000..7478d296e --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/KeyStorage.json @@ -0,0 +1,366 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "KeyStorage", + "sourceName": "contracts/schain/KeyStorage.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FN_NUM_GET_CONFIG_VARIABLE_UINT256", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FREE_MEM_PTR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlsCommonPublicKey", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "internalType": "struct IFieldOperations.Fp2Point", + "name": "x", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "internalType": "struct IFieldOperations.Fp2Point", + "name": "y", + "type": "tuple" + } + ], + "internalType": "struct IFieldOperations.G2Point", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610dc4806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80639010d07c1161008c578063ab2a585311610066578063ab2a5853146101db578063ca15c873146101e3578063d547741f146101f6578063ecfc7efe1461020957600080fd5b80639010d07c1461019557806391d14854146101c0578063a217fddf146101d357600080fd5b806336568abe116100c857806336568abe1461015d578063554ef7a614610170578063573c8aba146101855780638129fc1c1461018d57600080fd5b806301ffc9a7146100ef578063248a9ca3146101175780632f2ff15d14610148575b600080fd5b6101026100fd366004610b3e565b610211565b60405190151581526020015b60405180910390f35b61013a610125366004610b68565b60009081526065602052604090206001015490565b60405190815260200161010e565b61015b610156366004610b81565b61023c565b005b61015b61016b366004610b81565b610266565b6101786102e9565b60405161010e9190610bbd565b61013a604081565b61015b6102fe565b6101a86101a3366004610bec565b61041a565b6040516001600160a01b03909116815260200161010e565b6101026101ce366004610b81565b610439565b61013a600081565b61013a601381565b61013a6101f1366004610b68565b610464565b61015b610204366004610b81565b61047b565b61013a601981565b60006001600160e01b03198216635a05180f60e01b14806102365750610236826104a0565b92915050565b600082815260656020526040902060010154610257816104d5565b61026183836104df565b505050565b6001600160a01b03811633146102db5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6102e58282610501565b5050565b6102f1610afa565b6102f9610523565b905090565b600054610100900460ff161580801561031e5750600054600160ff909116105b806103385750303b158015610338575060005460ff166001145b61039b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102d2565b6000805460ff1916600117905580156103be576000805461ff0019166101001790555b6103c66105e3565b6103d1600033610650565b8015610417576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000828152609760205260408120610432908361065a565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b600081815260976020526040812061023690610666565b600082815260656020526040902060010154610496816104d5565b6102618383610501565b60006001600160e01b03198216637965db0b60e01b148061023657506301ffc9a760e01b6001600160e01b0319831614610236565b6104178133610670565b6104e982826106d4565b6000828152609760205260409020610261908261075a565b61050b828261076f565b600082815260976020526040902061026190826107d6565b61052b610afa565b600060409050600080600080600085516080816000836019600019fa815160208084015160408501516060909501518c518490528c5183018290528c83018051879052519092018290529298509096509094509092509050846105da5760405162461bcd60e51b815260206004820152602160248201527f4765742063757272656e7420424c53207075626c6963206b6579206661696c656044820152601960fa1b60648201526084016102d2565b50505050505090565b600054610100900460ff1661064e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016102d2565b565b6102e582826104df565b600061043283836107eb565b6000610236825490565b61067a8282610439565b6102e557610692816001600160a01b03166014610815565b61069d836020610815565b6040516020016106ae929190610c32565b60408051601f198184030181529082905262461bcd60e51b82526102d291600401610ca7565b6106de8282610439565b6102e55760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107163390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610432836001600160a01b0384166109b1565b6107798282610439565b156102e55760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610432836001600160a01b038416610a00565b600082600001828154811061080257610802610cda565b9060005260206000200154905092915050565b60606000610824836002610d06565b61082f906002610d25565b67ffffffffffffffff81111561084757610847610d38565b6040519080825280601f01601f191660200182016040528015610871576020820181803683370190505b509050600360fc1b8160008151811061088c5761088c610cda565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106108bb576108bb610cda565b60200101906001600160f81b031916908160001a90535060006108df846002610d06565b6108ea906001610d25565b90505b6001811115610962576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061091e5761091e610cda565b1a60f81b82828151811061093457610934610cda565b60200101906001600160f81b031916908160001a90535060049490941c9361095b81610d4e565b90506108ed565b5083156104325760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016102d2565b60008181526001830160205260408120546109f857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610236565b506000610236565b60008181526001830160205260408120548015610ae9576000610a24600183610d65565b8554909150600090610a3890600190610d65565b9050818114610a9d576000866000018281548110610a5857610a58610cda565b9060005260206000200154905080876000018481548110610a7b57610a7b610cda565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610aae57610aae610d78565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610236565b6000915050610236565b5092915050565b60408051608081018252600091810182815260608201929092529081908152602001610b39604051806040016040528060008152602001600081525090565b905290565b600060208284031215610b5057600080fd5b81356001600160e01b03198116811461043257600080fd5b600060208284031215610b7a57600080fd5b5035919050565b60008060408385031215610b9457600080fd5b8235915060208301356001600160a01b0381168114610bb257600080fd5b809150509250929050565b815180518252602090810151908201526080810160208381015180516040850152908101516060840152610af3565b60008060408385031215610bff57600080fd5b50508035926020909101359150565b60005b83811015610c29578181015183820152602001610c11565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351610c6a816017850160208801610c0e565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351610c9b816028840160208801610c0e565b01602801949350505050565b6020815260008251806020840152610cc6816040850160208701610c0e565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615610d2057610d20610cf0565b500290565b8082018082111561023657610236610cf0565b634e487b7160e01b600052604160045260246000fd5b600081610d5d57610d5d610cf0565b506000190190565b8181038181111561023657610236610cf0565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209eb591a65bac8d1c788efa82781806a242f292ebf8c3827b20d69ee3868daec864736f6c63430008100033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80639010d07c1161008c578063ab2a585311610066578063ab2a5853146101db578063ca15c873146101e3578063d547741f146101f6578063ecfc7efe1461020957600080fd5b80639010d07c1461019557806391d14854146101c0578063a217fddf146101d357600080fd5b806336568abe116100c857806336568abe1461015d578063554ef7a614610170578063573c8aba146101855780638129fc1c1461018d57600080fd5b806301ffc9a7146100ef578063248a9ca3146101175780632f2ff15d14610148575b600080fd5b6101026100fd366004610b3e565b610211565b60405190151581526020015b60405180910390f35b61013a610125366004610b68565b60009081526065602052604090206001015490565b60405190815260200161010e565b61015b610156366004610b81565b61023c565b005b61015b61016b366004610b81565b610266565b6101786102e9565b60405161010e9190610bbd565b61013a604081565b61015b6102fe565b6101a86101a3366004610bec565b61041a565b6040516001600160a01b03909116815260200161010e565b6101026101ce366004610b81565b610439565b61013a600081565b61013a601381565b61013a6101f1366004610b68565b610464565b61015b610204366004610b81565b61047b565b61013a601981565b60006001600160e01b03198216635a05180f60e01b14806102365750610236826104a0565b92915050565b600082815260656020526040902060010154610257816104d5565b61026183836104df565b505050565b6001600160a01b03811633146102db5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6102e58282610501565b5050565b6102f1610afa565b6102f9610523565b905090565b600054610100900460ff161580801561031e5750600054600160ff909116105b806103385750303b158015610338575060005460ff166001145b61039b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102d2565b6000805460ff1916600117905580156103be576000805461ff0019166101001790555b6103c66105e3565b6103d1600033610650565b8015610417576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000828152609760205260408120610432908361065a565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b600081815260976020526040812061023690610666565b600082815260656020526040902060010154610496816104d5565b6102618383610501565b60006001600160e01b03198216637965db0b60e01b148061023657506301ffc9a760e01b6001600160e01b0319831614610236565b6104178133610670565b6104e982826106d4565b6000828152609760205260409020610261908261075a565b61050b828261076f565b600082815260976020526040902061026190826107d6565b61052b610afa565b600060409050600080600080600085516080816000836019600019fa815160208084015160408501516060909501518c518490528c5183018290528c83018051879052519092018290529298509096509094509092509050846105da5760405162461bcd60e51b815260206004820152602160248201527f4765742063757272656e7420424c53207075626c6963206b6579206661696c656044820152601960fa1b60648201526084016102d2565b50505050505090565b600054610100900460ff1661064e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016102d2565b565b6102e582826104df565b600061043283836107eb565b6000610236825490565b61067a8282610439565b6102e557610692816001600160a01b03166014610815565b61069d836020610815565b6040516020016106ae929190610c32565b60408051601f198184030181529082905262461bcd60e51b82526102d291600401610ca7565b6106de8282610439565b6102e55760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107163390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610432836001600160a01b0384166109b1565b6107798282610439565b156102e55760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610432836001600160a01b038416610a00565b600082600001828154811061080257610802610cda565b9060005260206000200154905092915050565b60606000610824836002610d06565b61082f906002610d25565b67ffffffffffffffff81111561084757610847610d38565b6040519080825280601f01601f191660200182016040528015610871576020820181803683370190505b509050600360fc1b8160008151811061088c5761088c610cda565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106108bb576108bb610cda565b60200101906001600160f81b031916908160001a90535060006108df846002610d06565b6108ea906001610d25565b90505b6001811115610962576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061091e5761091e610cda565b1a60f81b82828151811061093457610934610cda565b60200101906001600160f81b031916908160001a90535060049490941c9361095b81610d4e565b90506108ed565b5083156104325760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016102d2565b60008181526001830160205260408120546109f857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610236565b506000610236565b60008181526001830160205260408120548015610ae9576000610a24600183610d65565b8554909150600090610a3890600190610d65565b9050818114610a9d576000866000018281548110610a5857610a58610cda565b9060005260206000200154905080876000018481548110610a7b57610a7b610cda565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610aae57610aae610d78565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610236565b6000915050610236565b5092915050565b60408051608081018252600091810182815260608201929092529081908152602001610b39604051806040016040528060008152602001600081525090565b905290565b600060208284031215610b5057600080fd5b81356001600160e01b03198116811461043257600080fd5b600060208284031215610b7a57600080fd5b5035919050565b60008060408385031215610b9457600080fd5b8235915060208301356001600160a01b0381168114610bb257600080fd5b809150509250929050565b815180518252602090810151908201526080810160208381015180516040850152908101516060840152610af3565b60008060408385031215610bff57600080fd5b50508035926020909101359150565b60005b83811015610c29578181015183820152602001610c11565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351610c6a816017850160208801610c0e565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351610c9b816028840160208801610c0e565b01602801949350505050565b6020815260008251806020840152610cc6816040850160208701610c0e565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615610d2057610d20610cf0565b500290565b8082018082111561023657610236610cf0565b634e487b7160e01b600052604160045260246000fd5b600081610d5d57610d5d610cf0565b506000190190565b8181038181111561023657610236610cf0565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209eb591a65bac8d1c788efa82781806a242f292ebf8c3827b20d69ee3868daec864736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/KeyStorage.meta.json b/predeployed/src/ima_predeployed/artifacts/KeyStorage.meta.json new file mode 100644 index 000000000..697708c59 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/KeyStorage.meta.json @@ -0,0 +1,410 @@ +{ + "name": "KeyStorage", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.dbg.json b/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.json b/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.json new file mode 100644 index 000000000..2f909e809 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.json @@ -0,0 +1,1100 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "MessageProxyForSchain", + "sourceName": "contracts/schain/MessageProxyForSchain.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "ExtraContractRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "ExtraContractRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "GasLimitWasChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "dstChainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "msgCounter", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "srcContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "dstContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "OutgoingMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "msgCounter", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "name": "PostMessageError", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "currentMessage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousOutgoingMessageBlockId", + "type": "uint256" + } + ], + "name": "PreviousMessageReference", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "oldVersion", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "newVersion", + "type": "string" + } + ], + "name": "VersionUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "CHAIN_CONNECTOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CONSTANT_SETTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ETHERBASE", + "outputs": [ + { + "internalType": "contract IEtherbaseUpgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "EXTRA_CONTRACT_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MESSAGES_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINIMUM_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REVERT_REASON_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chainName", + "type": "string" + } + ], + "name": "addConnectedChain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "connectedChains", + "outputs": [ + { + "internalType": "uint256", + "name": "incomingMessageCounter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "outgoingMessageCounter", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "inited", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "lastOutgoingMessageBlockId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "schainHash", + "type": "bytes32" + } + ], + "name": "getContractRegisteredLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "schainHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "to", + "type": "uint256" + } + ], + "name": "getContractRegisteredRange", + "outputs": [ + { + "internalType": "address[]", + "name": "contractsInRange", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "fromSchainName", + "type": "string" + } + ], + "name": "getIncomingMessagesCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + } + ], + "name": "getLastOutgoingMessageBlockId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + } + ], + "name": "getOutgoingMessagesCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IKeyStorage", + "name": "blsKeyStorage", + "type": "address" + }, + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newGasLimit", + "type": "uint256" + } + ], + "name": "initializeMessageProxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "isConnectedChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "schainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "isContractRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "keyStorage", + "outputs": [ + { + "internalType": "contract IKeyStorage", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messageInProgress", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "fromChainName", + "type": "string" + }, + { + "internalType": "uint256", + "name": "startingCounter", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "destinationContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IMessageProxy.Message[]", + "name": "messages", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "blsSignature", + "type": "uint256[2]" + }, + { + "internalType": "uint256", + "name": "hashA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hashB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + } + ], + "internalType": "struct IMessageProxy.Signature", + "name": "signature", + "type": "tuple" + } + ], + "name": "postIncomingMessages", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "targetChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "targetContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postOutgoingMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chainName", + "type": "string" + }, + { + "internalType": "address", + "name": "extraContract", + "type": "address" + } + ], + "name": "registerExtraContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "extraContract", + "type": "address" + } + ], + "name": "registerExtraContractForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chainName", + "type": "string" + } + ], + "name": "removeConnectedChain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "chainName", + "type": "string" + }, + { + "internalType": "address", + "name": "extraContract", + "type": "address" + } + ], + "name": "removeExtraContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "extraContract", + "type": "address" + } + ], + "name": "removeExtraContractForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newGasLimit", + "type": "uint256" + } + ], + "name": "setNewGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newVersion", + "type": "string" + } + ], + "name": "setVersion", + "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": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "dstChainHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "msgCounter", + "type": "uint256" + }, + { + "internalType": "address", + "name": "srcContract", + "type": "address" + }, + { + "internalType": "address", + "name": "dstContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IMessageProxyForSchain.OutgoingMessageData", + "name": "message", + "type": "tuple" + } + ], + "name": "verifyOutgoingMessageData", + "outputs": [ + { + "internalType": "bool", + "name": "isValidMessage", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hashedMessage", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "blsSignature", + "type": "uint256[2]" + }, + { + "internalType": "uint256", + "name": "hashA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hashB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + } + ], + "internalType": "struct IMessageProxy.Signature", + "name": "signature", + "type": "tuple" + } + ], + "name": "verifySignature", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5061424d806100206000396000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80636a156b9a11610151578063bbc4e8c2116100c3578063e6ab840311610087578063e6ab8403146105a3578063f2f6360514610604578063f399e22e14610617578063f68016b71461062a578063f79f795414610633578063f8c88a161461064657600080fd5b8063bbc4e8c21461053b578063bdb40cb014610562578063ca15c8731461056a578063cab010c91461057d578063d547741f1461059057600080fd5b80639010d07c116101155780639010d07c146104d457806391d14854146104e757806394489202146104fa578063999ab9aa1461050d578063a217fddf14610520578063a8bb1b7d1461052857600080fd5b80636a156b9a146104635780636e2f37b01461048857806377fe0f311461049b578063788bc78c146104ae5780637aa38a7c146104c157600080fd5b80633b690b6b116101ea57806352dc24ee116101ae57806352dc24ee146103f357806353498cdd1461040657806354fd4d5014610415578063603e5d131461042a578063654d88281461043d57806367ec60201461045057600080fd5b80633b690b6b1461039c5780633bf2f737146103a55780633cdd2cc3146103b85780634d203859146103cb578063523c8ab6146103de57600080fd5b8063214883401161023c57806321488340146102ec578063248a9ca31461030c57806328c5e1821461032f5780632f2ff15d1461036157806336568abe146103765780633b597ffe1461038957600080fd5b806301ffc9a7146102795780630fc307a8146102a157806313c52260146102c2578063198e687c146102d75780631cf5379d146102df575b600080fd5b61028c6102873660046133eb565b610659565b60405190151581526020015b60405180910390f35b6102b46102af366004613415565b610684565b604051908152602001610298565b6102b46000805160206141d883398151915281565b6102b4604081565b60d35461028c9060ff1681565b6102ff6102fa36600461342e565b61069b565b604051610298919061345a565b6102b461031a366004613415565b60009081526065602052604090206001015490565b6102b46040516613585a5b9b995d60ca1b60208201526027016040516020818303038152906040528051906020012081565b61037461036f3660046134bc565b6107da565b005b6103746103843660046134bc565b610804565b610374610397366004613415565b610882565b6102b460cd5481565b6102b46103b33660046135e5565b610948565b6103746103c63660046135e5565b6109be565b6103746103d9366004613619565b610aa7565b6102b460008051602061419883398151915281565b61028c610401366004613648565b610be1565b6102b4670de0b6b3a764000081565b61041d610bf4565b60405161029891906136c5565b610374610438366004613720565b610c82565b61028c61044b3660046134bc565b610f25565b6102b461045e3660046137da565b610f3d565b61047062695d1f60891b81565b6040516001600160a01b039091168152602001610298565b610374610496366004613415565b610fb6565b6102b46104a93660046137da565b6110ea565b6103746104bc3660046137da565b611190565b61028c6104cf36600461381b565b611230565b6104706104e23660046138c5565b611269565b61028c6104f53660046134bc565b611281565b6103746105083660046138e7565b6112ac565b61028c61051b3660046135e5565b611362565b6102b4600081565b610374610536366004613619565b6113ab565b6102b47f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c81565b6102b4600a81565b6102b4610578366004613415565b6114a5565b61037461058b36600461393f565b6114bc565b61037461059e3660046134bc565b611546565b6105de6105b1366004613415565b60c96020526000908152604090208054600182015460028301546003909301549192909160ff9091169084565b604080519485526020850193909352901515918301919091526060820152608001610298565b6103746106123660046137da565b61156b565b610374610625366004613985565b6115f2565b6102b460cb5481565b60cc54610470906001600160a01b031681565b61037461065436600461393f565b6117a3565b60006001600160e01b03198216635a05180f60e01b148061067e575061067e8261182d565b92915050565b600081815260d16020526040812061067e90611862565b606081831080156106b65750600a6106b384846139ea565b11155b80156106d85750600084815260d1602052604090206106d490611862565b8211155b61071e5760405162461bcd60e51b815260206004820152601260248201527114985b99d9481a5cc81a5b98dbdc9c9958dd60721b60448201526064015b60405180910390fd5b61072883836139ea565b6001600160401b0381111561073f5761073f6134ec565b604051908082528060200260200182016040528015610768578160200160208202803683370190505b509050825b828110156107d257600085815260d16020526040902061078d908261186c565b8261079886846139ea565b815181106107a8576107a86139fd565b6001600160a01b0390921660209283029190910190910152806107ca81613a13565b91505061076d565b509392505050565b6000828152606560205260409020600101546107f581611878565b6107ff8383611885565b505050565b6001600160a01b03811633146108745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610715565b61087e82826118a7565b5050565b6108ac7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33611281565b6109075760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2073657420636f6044820152651b9cdd185b9d60d21b6064820152608401610715565b60cb5460408051918252602082018390527f8abddb75fd50f7583079c0b550ec7a54fa3fd8d5dd1d2dfdc473f7ce27e3b9ac910160405180910390a160cb55565b6000808260405160200161095c9190613a2c565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff166109a65760405162461bcd60e51b815260040161071590613a48565b600090815260c9602052604090206003015492915050565b6109d66000805160206141d883398151915233611281565b6109f25760405162461bcd60e51b815260040161071590613a8c565b600081604051602001610a059190613a2c565b604051602081830303815290604052805190602001209050604051602001610a3a906613585a5b9b995d60ca1b815260070190565b604051602081830303815290604052805190602001208103610a9e5760405162461bcd60e51b815260206004820152601960248201527f4d61696e6e65742063616e6e6f742062652072656d6f766564000000000000006044820152606401610715565b61087e826118c9565b610abf60008051602061419883398151915233611281565b610adb5760405162461bcd60e51b815260040161071590613ac1565b6001600160a01b0381163b610b325760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401610715565b610b4e8160d15b600080805260209190915260409020906119b0565b15610b6b5760405162461bcd60e51b815260040161071590613b0a565b6000805260d1602052610b9d7efa5413e7b01fc543d01f0911de573ace463b956369df4472f39030e8d98b77826119d2565b506040516001600160a01b03821681526000907f03bcd152926369e3cf05cb7af471a15d680e8ec5d20b13705048d14e94679365906020015b60405180910390a250565b6000610bed83836119e7565b9392505050565b60d28054610c0190613b4e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2d90613b4e565b8015610c7a5780601f10610c4f57610100808354040283529160200191610c7a565b820191906000526020600020905b815481529060010190602001808311610c5d57829003601f168201915b505050505081565b60d35460ff1615610cce5760405162461bcd60e51b81526020600482015260166024820152754d65737361676520697320696e2070726f677265737360501b6044820152606401610715565b60d3805460ff19166001179055604051600090610cf19088908890602001613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff16610d665760405162461bcd60e51b815260206004820152601860248201527710da185a5b881a5cc81b9bdd081a5b9a5d1a585b1a5e995960421b6044820152606401610715565b600a831115610dab5760405162461bcd60e51b8152602060048201526011602482015270546f6f206d616e79206d6573736167657360781b6044820152606401610715565b610dc1610dbb8585888b8b611a85565b836119e7565b610e0d5760405162461bcd60e51b815260206004820152601960248201527f5369676e6174757265206973206e6f74207665726966696564000000000000006044820152606401610715565b600081815260c960205260409020548514610e905760405162461bcd60e51b815260206004820152603860248201527f5374617274696e6720636f756e746572206973206e6f74207175616c20746f2060448201527f696e636f6d696e67206d65737361676520636f756e74657200000000000000006064820152608401610715565b600081815260c9602052604081208054859290610eae908490613b92565b90915550600090505b83811015610f0957610ef782868684818110610ed557610ed56139fd565b9050602002810190610ee79190613ba5565b610ef2896001613b92565b611c00565b80610f0181613a13565b915050610eb7565b50610f12611e23565b505060d3805460ff191690555050505050565b600082815260d160205260408120610bed90836119b0565b6000808383604051602001610f53929190613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff16610f9d5760405162461bcd60e51b815260040161071590613a48565b600090815260c960205260409020600101549392505050565b600054610100900460ff1615808015610fd65750600054600160ff909116105b80610ff05750303b158015610ff0575060005460ff166001145b61100c5760405162461bcd60e51b815260040161071590613bbb565b6000805460ff19166001179055801561102f576000805461ff0019166101001790555b611037611ff9565b611042600033612066565b61105a6000805160206141d883398151915233612066565b61107260008051602061419883398151915233612066565b61109c7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33612066565b60cb829055801561087e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000808383604051602001611100929190613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff1661117a5760405162461bcd60e51b815260206004820152601f60248201527f536f7572636520636861696e206973206e6f7420696e697469616c697a6564006044820152606401610715565b600090815260c960205260409020549392505050565b61119b600033611281565b6111e75760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401610715565b7f22efc5f993dce37856b77dd72d7d7661032380c9728c4133f3c071c591bc6ca760d2838360405161121b93929190613c32565b60405180910390a160d26107ff828483613d17565b8051600090815260ce6020908152604080832082850151845290915281205461125883612070565b810361126357600191505b50919050565b6000828152609760205260408120610bed908361186c565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6112b78383836120e6565b60006040518060a00160405280858152602001600160c96000888152602001908152602001600020600101546112ed91906139ea565b81523360208201526001600160a01b0385166040820152606001839052805190915061131882612070565b600082815260ce6020908152604080832060d08084528285208054865291845291842094909455848352905281546001929190611356908490613b92565b90915550505050505050565b600060c96000836040516020016113799190613a2c565b60408051601f198184030181529181528151602092830120835290820192909252016000206002015460ff1692915050565b6113c360008051602061419883398151915233611281565b6113df5760405162461bcd60e51b815260040161071590613ac1565b6113ea8160d1610b39565b6114365760405162461bcd60e51b815260206004820181905260248201527f457874726120636f6e7472616374206973206e6f7420726567697374657265646044820152606401610715565b6000805260d16020526114687efa5413e7b01fc543d01f0911de573ace463b956369df4472f39030e8d98b77826121f9565b506040516001600160a01b03821681526000907f4d393b64277bfc0b02e0459a74c316c7f22069352a678319fd8139ba4085e06190602001610bd6565b600081815260976020526040812061067e90611862565b6114d460008051602061419883398151915233611281565b6114f05760405162461bcd60e51b815260040161071590613ac1565b6000826040516020016115039190613a2c565b60405160208183030381529060405280519060200120905060cd54810361153c5760405162461bcd60e51b815260040161071590613dd7565b6107ff818361220e565b60008281526065602052604090206001015461156181611878565b6107ff83836118a7565b60008282604051602001611580929190613b82565b60405160208183030381529060405280519060200120905060cd5481036115e95760405162461bcd60e51b815260206004820152601c60248201527f53636861696e2063616e6e6f7420636f6e6e65637420697473656c66000000006044820152606401610715565b6107ff8161236e565b600054610100900460ff16158080156116125750600054600160ff909116105b8061162c5750303b15801561162c575060005460ff166001145b6116485760405162461bcd60e51b815260040161071590613bbb565b6000805460ff19166001179055801561166b576000805461ff0019166101001790555b611677622dc6c0610fb6565b60cc80546001600160a01b0385166001600160a01b03199091161790556040805160808101825260008082526020808301829052600183850152606083018290529251919260c9926116d791016613585a5b9b995d60ca1b815260070190565b60408051808303601f190181529181528151602092830120835282820193909352908201600020835181558382015160018201558383015160028201805460ff19169115159190911790556060909301516003909301929092555161173e91849101613a2c565b60408051601f19818403018152919052805160209091012060cd5580156107ff576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6117bb60008051602061419883398151915233611281565b6117d75760405162461bcd60e51b815260040161071590613ac1565b6000826040516020016117ea9190613a2c565b60405160208183030381529060405280519060200120905060cd5481036118235760405162461bcd60e51b815260040161071590613dd7565b6107ff8183612462565b60006001600160e01b03198216637965db0b60e01b148061067e57506301ffc9a760e01b6001600160e01b031983161461067e565b600061067e825490565b6000610bed838361250d565b6118828133612537565b50565b61188f828261259b565b60008281526097602052604090206107ff90826119d2565b6118b18282612621565b60008281526097602052604090206107ff90826121f9565b6118e16000805160206141d883398151915233611281565b6118fd5760405162461bcd60e51b815260040161071590613a8c565b6000816040516020016119109190613a2c565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff166119855760405162461bcd60e51b815260206004820152601860248201527710da185a5b881a5cc81b9bdd081a5b9a5d1a585b1a5e995960421b6044820152606401610715565b600090815260c9602052604081208181556001810182905560028101805460ff191690556003015550565b6001600160a01b03811660009081526001830160205260408120541515610bed565b6000610bed836001600160a01b038416612688565b604080518082018252823581526020808401359082015260cc548251632aa77bd360e11b81528351600094610bed949388936080808a013594938a01359360608b0135936001600160a01b03169263554ef7a69260048083019391928290030181865afa158015611a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a809190613e5d565b6126d7565b6000808383604051602001611a9b929190613b82565b60408051808303601f190181528282528051602091820120908301819052908201879052915060009060600160405160208183030381529060405280519060200120905060005b87811015611bf45781898983818110611afd57611afd6139fd565b9050602002810190611b0f9190613ba5565b611b1d906020810190613619565b8a8a84818110611b2f57611b2f6139fd565b9050602002810190611b419190613ba5565b611b52906040810190602001613619565b6040805160208101949094526001600160a01b0392831690840152166060820152608001604051602081830303815290604052898983818110611b9757611b976139fd565b9050602002810190611ba99190613ba5565b611bb7906040810190613ea0565b604051602001611bc993929190613ee6565b6040516020818303038152906040528051906020012091508080611bec90613a13565b915050611ae2565b50979650505050505050565b611c22611c136040840160208501613619565b6001600160a01b03163b151590565b611c9057806000805160206141f8833981519152604051611c839060208082526026908201527f44657374696e6174696f6e20636f6e7472616374206973206e6f74206120636f6040820152651b9d1c9858dd60d21b606082015260800190565b60405180910390a2505050565b611ca06040830160208401613619565b6001600160a01b031663884cee5a60cb5485856000016020810190611cc59190613619565b611cd26040880188613ea0565b6040518663ffffffff1660e01b8152600401611cf19493929190613f0e565b600060405180830381600088803b158015611d0b57600080fd5b5087f193505050508015611d1d575060015b6107ff57611d29613f39565b806308c379a003611d7e5750611d3d613f55565b80611d485750611dd8565b816000805160206141f8833981519152611d638360406128a1565b604051611d7091906136c5565b60405180910390a250505050565b634e487b7103611dd857611d90613fde565b90611d9b5750611dd8565b816000805160206141f883398151915282604051602001611dbe91815260200190565b60408051601f1981840301815290829052611d70916136c5565b3d808015611e02576040519150601f19603f3d011682016040523d82523d6000602084013e611e07565b606091505b50816000805160206141f8833981519152611d638360406128a1565b60003a5a611e319190613ffe565b611e3c903331613b92565b905062695d1f60891b803b15801590611f275750806001600160a01b03166391d14854826001600160a01b031663bc2a1e8d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec1919061401d565b6040516001600160e01b031960e084901b1681526004810191909152306024820152604401602060405180830381865afa158015611f03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f279190614036565b8015611f3a5750670de0b6b3a764000082105b1561087e576000611f5383670de0b6b3a76400006139ea565b9050816001600160a01b031631811015611fcd5760405163204a3e9360e01b8152336004820152602481018290526001600160a01b0383169063204a3e93906044015b600060405180830381600087803b158015611fb057600080fd5b505af1158015611fc4573d6000803e3d6000fd5b50505050505050565b604051630a79309b60e01b81523360048201526001600160a01b03831690630a79309b90602401611f96565b600054610100900460ff166120645760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610715565b565b61087e8282611885565b6000808260000151836020015160001b846040015160601b6bffffffffffffffffffffffff1916856060015160601b6bffffffffffffffffffffffff191686608001516040516020016120c7959493929190614058565b60408051601f1981840301815291905280516020909101209392505050565b600083815260c9602052604090206002015460ff166121175760405162461bcd60e51b815260040161071590613a48565b6121208361296b565b600083815260c96020526040908190206001015490513390829086907f803d7f3ca0e5f93fcce39fa29812ed57a95a151594966e17125220132741c6b09061216b9088908890614093565b60405180910390a4600084815260c96020908152604091829020600301548251848152918201527f64ab4eb9f2b913fd01467c69e91e32483420fab6be93c3a7559adbe1b0356845910160405180910390a1600084815260c9602052604081206001018054916121da83613a13565b9091555050506000928352505060c96020526040902043600390910155565b6000610bed836001600160a01b0384166129dc565b6001600160a01b0381163b6122655760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401610715565b6122818160d15b600085815260209190915260409020906119b0565b1561229e5760405162461bcd60e51b815260040161071590613b0a565b6122a98160d1610b39565b156123125760405162461bcd60e51b815260206004820152603360248201527f457874726120636f6e747261637420697320616c7265616479207265676973746044820152726572656420666f7220616c6c20636861696e7360681b6064820152608401610715565b600082815260d16020526040902061232a90826119d2565b506040516001600160a01b038216815282907f03bcd152926369e3cf05cb7af471a15d680e8ec5d20b13705048d14e94679365906020015b60405180910390a25050565b6123866000805160206141d883398151915233611281565b6123a25760405162461bcd60e51b815260040161071590613a8c565b600081815260c9602052604090206002015460ff16156124045760405162461bcd60e51b815260206004820152601a60248201527f436861696e20697320616c726561647920636f6e6e65637465640000000000006044820152606401610715565b604080516080810182526000808252602080830182815260018486018181526060860185815297855260c99093529490922092518355905192820192909255905160028201805460ff19169115159190911790559051600390910155565b61246d8160d161226c565b6124b95760405162461bcd60e51b815260206004820181905260248201527f457874726120636f6e7472616374206973206e6f7420726567697374657265646044820152606401610715565b600082815260d1602052604090206124d190826121f9565b506040516001600160a01b038216815282907f4d393b64277bfc0b02e0459a74c316c7f22069352a678319fd8139ba4085e06190602001612362565b6000826000018281548110612524576125246139fd565b9060005260206000200154905092915050565b6125418282611281565b61087e57612559816001600160a01b03166014612ad6565b612564836020612ad6565b6040516020016125759291906140b7565b60408051601f198184030181529082905262461bcd60e51b8252610715916004016136c5565b6125a58282611281565b61087e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556125dd3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61262b8282611281565b1561087e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120546126cf5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561067e565b50600061067e565b60006126e287612c71565b6127275760405162461bcd60e51b815260206004820152601660248201527514da59db985d1d5c99481a5cc81b9bdd081d985b1a5960521b6044820152606401610715565b61273386868686612ca7565b61273f57506000612897565b600061274e8860200151612d95565b905061275e886000015182612dba565b61279b5760405162461bcd60e51b815260206004820152600e60248201526d5369676e206e6f7420696e20473160901b6044820152606401610715565b6127a58585612dba565b6127e25760405162461bcd60e51b815260206004820152600e60248201526d48617368206e6f7420696e20473160901b6044820152606401610715565b60006127ec612df0565b90506127f784612eb0565b61283a5760405162461bcd60e51b8152602060048201526014602482015273283ab13634b19025b2bc903737ba1034b710239960611b6044820152606401610715565b6128928960000151838360000151602001518460000151600001518560200151602001518660200151600001518c8c8c60000151602001518d60000151600001518e60200151602001518f6020015160000151612ec4565b925050505b9695505050505050565b60606000835183106128b45783516128b6565b825b90506000816001600160401b038111156128d2576128d26134ec565b6040519080825280601f01601f1916602001820160405280156128fc576020820181803683370190505b50905060005b828110156129625785818151811061291c5761291c6139fd565b602001015160f81c60f81b828281518110612939576129396139fd565b60200101906001600160f81b031916908160001a9053508061295a81613a13565b915050612902565b50949350505050565b612976600033610f25565b8061298657506129868133610f25565b6118825760405162461bcd60e51b815260206004820152602160248201527f53656e64657220636f6e7472616374206973206e6f74207265676973746572656044820152601960fa1b6064820152608401610715565b60008181526001830160205260408120548015612ac5576000612a006001836139ea565b8554909150600090612a14906001906139ea565b9050818114612a79576000866000018281548110612a3457612a346139fd565b9060005260206000200154905080876000018481548110612a5757612a576139fd565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612a8a57612a8a61412c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061067e565b600091505061067e565b5092915050565b60606000612ae5836002613ffe565b612af0906002613b92565b6001600160401b03811115612b0757612b076134ec565b6040519080825280601f01601f191660200182016040528015612b31576020820181803683370190505b509050600360fc1b81600081518110612b4c57612b4c6139fd565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612b7b57612b7b6139fd565b60200101906001600160f81b031916908160001a9053506000612b9f846002613ffe565b612baa906001613b92565b90505b6001811115612c22576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612bde57612bde6139fd565b1a60f81b828281518110612bf457612bf46139fd565b60200101906001600160f81b031916908160001a90535060049490941c93612c1b81614142565b9050612bad565b508315610bed5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610715565b60006000805160206141b8833981519152826000015110801561067e575050602001516000805160206141b88339815191521190565b60006064841115612cba57506000612d8d565b6000612cd46000805160206141b88339815191528761416f565b90506000805160206141b8833981519152612cef8683613b92565b612cf9919061416f565b905060006000805160206141b883398151915260036000805160206141b8833981519152846000805160206141b883398151915286870909089050612d4d60026000805160206141b8833981519152614183565b841080612d6b5750806000805160206141b883398151915285860914155b80612d765750848214155b15612d8657600092505050612d8d565b6001925050505b949350505050565b60006000805160206141b8833981519152612db083826139ea565b61067e919061416f565b60006000805160206141b883398151915280600381868188890909088180612de457612de4614159565b84850914949350505050565b612df861336a565b50604080516080810182527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed8183019081527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26060830152815281518083019092527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa82527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60208381019190915281019190915290565b600061067e82600001518360200151612f94565b600080612ecf6133ae565b8e8152602081018e9052604081018d9052606081018c9052608081018b905260a081018a905260c0810189905260e081018890526101008101879052610120810186905261014081018590526101608101849052612f2b6133cd565b602081610180846008600019fa925082612f7e5760405162461bcd60e51b815260206004820152601460248201527314185a5c9a5b99c818da1958dac819985a5b195960621b6044820152606401610715565b5115159f9e505050505050505050505050505050565b6000612fa08383613068565b15612fad5750600161067e565b6000612fb88361309b565b9050600061304b613028604080518082018252600080825260209182015281518083019092527f2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e582527e9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d29082015290565b61304561303e886130388a61309b565b90613151565b8590613264565b90613264565b805190915015801561305f57506020810151155b95945050505050565b815160009015801561307c57506020830151155b8015613089575081516001145b8015610bed5750506020015115919050565b60408051808201909152600080825260208201526000805160206141b883398151915260008160208501518551099050600082806130db576130db614159565b83806130e9576130e9614159565b84806130f7576130f7614159565b60208801516131076001886139ea565b09875108848061311957613119614159565b60208801518851080990506040518060400160405280828152602001848061314357613143614159565b848508905295945050505050565b604080518082019091526000808252602082015260006000805160206141b8833981519152905060006040518060400160405280838061319357613193614159565b8651885109815260200183806131ab576131ab614159565b86602001518860200151099052905081806131c8576131c8614159565b82806131d6576131d6614159565b60208301516131e66001866139ea565b09825108835281806131fa576131fa614159565b828061320857613208614159565b602083015183510861321a90846139ea565b838061322857613228614159565b848061323657613236614159565b6020880151885108858061324c5761324c614159565b60208a01518a51080908602084015250909392505050565b6040805180820190915260008082526020820152815183516000805160206141b883398151915291116132b557808061329f5761329f614159565b83516132ab90836139ea565b85510882526132ea565b8081806132c4576132c4614159565b85516132d090846139ea565b8551086132dd90836139ea565b6132e7919061416f565b82525b826020015184602001511061332657808061330757613307614159565b602084015161331690836139ea565b8560200151086020830152612acf565b80818061333557613335614159565b602086015161334490846139ea565b85602001510861335490836139ea565b61335e919061416f565b60208301525092915050565b604080516080810182526000918101828152606082019290925290819081526020016133a9604051806040016040528060008152602001600081525090565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b6000602082840312156133fd57600080fd5b81356001600160e01b031981168114610bed57600080fd5b60006020828403121561342757600080fd5b5035919050565b60008060006060848603121561344357600080fd5b505081359360208301359350604090920135919050565b6020808252825182820181905260009190848201906040850190845b8181101561349b5783516001600160a01b031683529284019291840191600101613476565b50909695505050505050565b6001600160a01b038116811461188257600080fd5b600080604083850312156134cf57600080fd5b8235915060208301356134e1816134a7565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60a081018181106001600160401b0382111715613521576135216134ec565b60405250565b604081018181106001600160401b0382111715613521576135216134ec565b601f8201601f191681016001600160401b038111828210171561356b5761356b6134ec565b6040525050565b600082601f83011261358357600080fd5b81356001600160401b0381111561359c5761359c6134ec565b6040516135b3601f8301601f191660200182613546565b8181528460208386010111156135c857600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156135f757600080fd5b81356001600160401b0381111561360d57600080fd5b612d8d84828501613572565b60006020828403121561362b57600080fd5b8135610bed816134a7565b600060a0828403121561126357600080fd5b60008060c0838503121561365b57600080fd5b8235915061366c8460208501613636565b90509250929050565b60005b83811015613690578181015183820152602001613678565b50506000910152565b600081518084526136b1816020860160208601613675565b601f01601f19169290920160200192915050565b602081526000610bed6020830184613699565b60008083601f8401126136ea57600080fd5b5081356001600160401b0381111561370157600080fd5b60208301915083602082850101111561371957600080fd5b9250929050565b600080600080600080610100878903121561373a57600080fd5b86356001600160401b038082111561375157600080fd5b61375d8a838b016136d8565b909850965060208901359550604089013591508082111561377d57600080fd5b818901915089601f83011261379157600080fd5b8135818111156137a057600080fd5b8a60208260051b85010111156137b557600080fd5b6020830195508094505050506137ce8860608901613636565b90509295509295509295565b600080602083850312156137ed57600080fd5b82356001600160401b0381111561380357600080fd5b61380f858286016136d8565b90969095509350505050565b60006020828403121561382d57600080fd5b81356001600160401b038082111561384457600080fd5b9083019060a0828603121561385857600080fd5b60405161386481613502565b82358152602083013560208201526040830135613880816134a7565b60408201526060830135613893816134a7565b60608201526080830135828111156138aa57600080fd5b6138b687828601613572565b60808301525095945050505050565b600080604083850312156138d857600080fd5b50508035926020909101359150565b6000806000606084860312156138fc57600080fd5b83359250602084013561390e816134a7565b915060408401356001600160401b0381111561392957600080fd5b61393586828701613572565b9150509250925092565b6000806040838503121561395257600080fd5b82356001600160401b0381111561396857600080fd5b61397485828601613572565b92505060208301356134e1816134a7565b6000806040838503121561399857600080fd5b82356139a3816134a7565b915060208301356001600160401b038111156139be57600080fd5b6139ca85828601613572565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561067e5761067e6139d4565b634e487b7160e01b600052603260045260246000fd5b600060018201613a2557613a256139d4565b5060010190565b60008251613a3e818460208701613675565b9190910192915050565b60208082526024908201527f44657374696e6174696f6e20636861696e206973206e6f7420696e697469616c6040820152631a5e995960e21b606082015260800190565b6020808252818101527f434841494e5f434f4e4e4543544f525f524f4c45206973207265717569726564604082015260600190565b60208082526029908201527f45585452415f434f4e54524143545f5245474953545241525f524f4c45206973604082015268081c995c5d5a5c995960ba1b606082015260800190565b60208082526024908201527f457874726120636f6e747261637420697320616c726561647920726567697374604082015263195c995960e21b606082015260800190565b600181811c90821680613b6257607f821691505b60208210810361126357634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b8082018082111561067e5761067e6139d4565b60008235605e19833603018112613a3e57600080fd5b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b604081526000808554613c4481613b4e565b8060408601526060600180841660008114613c665760018114613c8057613cb1565b60ff1985168884015283151560051b880183019550613cb1565b8a60005260208060002060005b86811015613ca85781548b8201870152908401908201613c8d565b8a018501975050505b50505050508281036020840152612897818587613c09565b601f8211156107ff57600081815260208120601f850160051c81016020861015613cf05750805b601f850160051c820191505b81811015613d0f57828155600101613cfc565b505050505050565b6001600160401b03831115613d2e57613d2e6134ec565b613d4283613d3c8354613b4e565b83613cc9565b6000601f841160018114613d765760008515613d5e5750838201355b600019600387901b1c1916600186901b178355613dd0565b600083815260209020601f19861690835b82811015613da75786850135825560209485019460019092019101613d87565b5086821015613dc45760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208082526030908201527f44657374696e6174696f6e20636861696e20686173682063616e6e6f7420626560408201526f1032b8bab0b6103a379034ba39b2b63360811b606082015260800190565b600060408284031215613e3957600080fd5b604051613e4581613527565b80915082518152602083015160208201525092915050565b600060808284031215613e6f57600080fd5b604051613e7b81613527565b613e858484613e27565b8152613e948460408501613e27565b60208201529392505050565b6000808335601e19843603018112613eb757600080fd5b8301803591506001600160401b03821115613ed157600080fd5b60200191503681900382131561371957600080fd5b60008451613ef8818460208901613675565b8201838582376000930192835250909392505050565b8481526001600160a01b03841660208201526060604082018190526000906128979083018486613c09565b600060033d1115613f525760046000803e5060005160e01c5b90565b600060443d1015613f635790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715613f9257505050505090565b8285019150815181811115613faa5750505050505090565b843d8701016020828501011115613fc45750505050505090565b613fd360208286010187613546565b509095945050505050565b60008060233d1115613ffa576020600460003e50506000516001905b9091565b6000816000190483118215151615614018576140186139d4565b500290565b60006020828403121561402f57600080fd5b5051919050565b60006020828403121561404857600080fd5b81518015158114610bed57600080fd5b85815284602082015283604082015282606082015260008251614082816080850160208701613675565b919091016080019695505050505050565b6001600160a01b0383168152604060208201819052600090612d8d90830184613699565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516140ef816017850160208801613675565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614120816028840160208801613675565b01602801949350505050565b634e487b7160e01b600052603160045260246000fd5b600081614151576141516139d4565b506000190190565b634e487b7160e01b600052601260045260246000fd5b60008261417e5761417e614159565b500690565b60008261419257614192614159565b50049056fe6155b5aac15ce9aa193c0527a6f43be0a36a7e2e7496c2b615c0e5f92284277330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd472785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e1914b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e59a26469706673582212202d276ec52211cb6b0422d5ff12645bf923438087729432e09c60f0ddc94bf80e64736f6c63430008100033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102745760003560e01c80636a156b9a11610151578063bbc4e8c2116100c3578063e6ab840311610087578063e6ab8403146105a3578063f2f6360514610604578063f399e22e14610617578063f68016b71461062a578063f79f795414610633578063f8c88a161461064657600080fd5b8063bbc4e8c21461053b578063bdb40cb014610562578063ca15c8731461056a578063cab010c91461057d578063d547741f1461059057600080fd5b80639010d07c116101155780639010d07c146104d457806391d14854146104e757806394489202146104fa578063999ab9aa1461050d578063a217fddf14610520578063a8bb1b7d1461052857600080fd5b80636a156b9a146104635780636e2f37b01461048857806377fe0f311461049b578063788bc78c146104ae5780637aa38a7c146104c157600080fd5b80633b690b6b116101ea57806352dc24ee116101ae57806352dc24ee146103f357806353498cdd1461040657806354fd4d5014610415578063603e5d131461042a578063654d88281461043d57806367ec60201461045057600080fd5b80633b690b6b1461039c5780633bf2f737146103a55780633cdd2cc3146103b85780634d203859146103cb578063523c8ab6146103de57600080fd5b8063214883401161023c57806321488340146102ec578063248a9ca31461030c57806328c5e1821461032f5780632f2ff15d1461036157806336568abe146103765780633b597ffe1461038957600080fd5b806301ffc9a7146102795780630fc307a8146102a157806313c52260146102c2578063198e687c146102d75780631cf5379d146102df575b600080fd5b61028c6102873660046133eb565b610659565b60405190151581526020015b60405180910390f35b6102b46102af366004613415565b610684565b604051908152602001610298565b6102b46000805160206141d883398151915281565b6102b4604081565b60d35461028c9060ff1681565b6102ff6102fa36600461342e565b61069b565b604051610298919061345a565b6102b461031a366004613415565b60009081526065602052604090206001015490565b6102b46040516613585a5b9b995d60ca1b60208201526027016040516020818303038152906040528051906020012081565b61037461036f3660046134bc565b6107da565b005b6103746103843660046134bc565b610804565b610374610397366004613415565b610882565b6102b460cd5481565b6102b46103b33660046135e5565b610948565b6103746103c63660046135e5565b6109be565b6103746103d9366004613619565b610aa7565b6102b460008051602061419883398151915281565b61028c610401366004613648565b610be1565b6102b4670de0b6b3a764000081565b61041d610bf4565b60405161029891906136c5565b610374610438366004613720565b610c82565b61028c61044b3660046134bc565b610f25565b6102b461045e3660046137da565b610f3d565b61047062695d1f60891b81565b6040516001600160a01b039091168152602001610298565b610374610496366004613415565b610fb6565b6102b46104a93660046137da565b6110ea565b6103746104bc3660046137da565b611190565b61028c6104cf36600461381b565b611230565b6104706104e23660046138c5565b611269565b61028c6104f53660046134bc565b611281565b6103746105083660046138e7565b6112ac565b61028c61051b3660046135e5565b611362565b6102b4600081565b610374610536366004613619565b6113ab565b6102b47f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c81565b6102b4600a81565b6102b4610578366004613415565b6114a5565b61037461058b36600461393f565b6114bc565b61037461059e3660046134bc565b611546565b6105de6105b1366004613415565b60c96020526000908152604090208054600182015460028301546003909301549192909160ff9091169084565b604080519485526020850193909352901515918301919091526060820152608001610298565b6103746106123660046137da565b61156b565b610374610625366004613985565b6115f2565b6102b460cb5481565b60cc54610470906001600160a01b031681565b61037461065436600461393f565b6117a3565b60006001600160e01b03198216635a05180f60e01b148061067e575061067e8261182d565b92915050565b600081815260d16020526040812061067e90611862565b606081831080156106b65750600a6106b384846139ea565b11155b80156106d85750600084815260d1602052604090206106d490611862565b8211155b61071e5760405162461bcd60e51b815260206004820152601260248201527114985b99d9481a5cc81a5b98dbdc9c9958dd60721b60448201526064015b60405180910390fd5b61072883836139ea565b6001600160401b0381111561073f5761073f6134ec565b604051908082528060200260200182016040528015610768578160200160208202803683370190505b509050825b828110156107d257600085815260d16020526040902061078d908261186c565b8261079886846139ea565b815181106107a8576107a86139fd565b6001600160a01b0390921660209283029190910190910152806107ca81613a13565b91505061076d565b509392505050565b6000828152606560205260409020600101546107f581611878565b6107ff8383611885565b505050565b6001600160a01b03811633146108745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610715565b61087e82826118a7565b5050565b6108ac7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33611281565b6109075760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2073657420636f6044820152651b9cdd185b9d60d21b6064820152608401610715565b60cb5460408051918252602082018390527f8abddb75fd50f7583079c0b550ec7a54fa3fd8d5dd1d2dfdc473f7ce27e3b9ac910160405180910390a160cb55565b6000808260405160200161095c9190613a2c565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff166109a65760405162461bcd60e51b815260040161071590613a48565b600090815260c9602052604090206003015492915050565b6109d66000805160206141d883398151915233611281565b6109f25760405162461bcd60e51b815260040161071590613a8c565b600081604051602001610a059190613a2c565b604051602081830303815290604052805190602001209050604051602001610a3a906613585a5b9b995d60ca1b815260070190565b604051602081830303815290604052805190602001208103610a9e5760405162461bcd60e51b815260206004820152601960248201527f4d61696e6e65742063616e6e6f742062652072656d6f766564000000000000006044820152606401610715565b61087e826118c9565b610abf60008051602061419883398151915233611281565b610adb5760405162461bcd60e51b815260040161071590613ac1565b6001600160a01b0381163b610b325760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401610715565b610b4e8160d15b600080805260209190915260409020906119b0565b15610b6b5760405162461bcd60e51b815260040161071590613b0a565b6000805260d1602052610b9d7efa5413e7b01fc543d01f0911de573ace463b956369df4472f39030e8d98b77826119d2565b506040516001600160a01b03821681526000907f03bcd152926369e3cf05cb7af471a15d680e8ec5d20b13705048d14e94679365906020015b60405180910390a250565b6000610bed83836119e7565b9392505050565b60d28054610c0190613b4e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2d90613b4e565b8015610c7a5780601f10610c4f57610100808354040283529160200191610c7a565b820191906000526020600020905b815481529060010190602001808311610c5d57829003601f168201915b505050505081565b60d35460ff1615610cce5760405162461bcd60e51b81526020600482015260166024820152754d65737361676520697320696e2070726f677265737360501b6044820152606401610715565b60d3805460ff19166001179055604051600090610cf19088908890602001613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff16610d665760405162461bcd60e51b815260206004820152601860248201527710da185a5b881a5cc81b9bdd081a5b9a5d1a585b1a5e995960421b6044820152606401610715565b600a831115610dab5760405162461bcd60e51b8152602060048201526011602482015270546f6f206d616e79206d6573736167657360781b6044820152606401610715565b610dc1610dbb8585888b8b611a85565b836119e7565b610e0d5760405162461bcd60e51b815260206004820152601960248201527f5369676e6174757265206973206e6f74207665726966696564000000000000006044820152606401610715565b600081815260c960205260409020548514610e905760405162461bcd60e51b815260206004820152603860248201527f5374617274696e6720636f756e746572206973206e6f74207175616c20746f2060448201527f696e636f6d696e67206d65737361676520636f756e74657200000000000000006064820152608401610715565b600081815260c9602052604081208054859290610eae908490613b92565b90915550600090505b83811015610f0957610ef782868684818110610ed557610ed56139fd565b9050602002810190610ee79190613ba5565b610ef2896001613b92565b611c00565b80610f0181613a13565b915050610eb7565b50610f12611e23565b505060d3805460ff191690555050505050565b600082815260d160205260408120610bed90836119b0565b6000808383604051602001610f53929190613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff16610f9d5760405162461bcd60e51b815260040161071590613a48565b600090815260c960205260409020600101549392505050565b600054610100900460ff1615808015610fd65750600054600160ff909116105b80610ff05750303b158015610ff0575060005460ff166001145b61100c5760405162461bcd60e51b815260040161071590613bbb565b6000805460ff19166001179055801561102f576000805461ff0019166101001790555b611037611ff9565b611042600033612066565b61105a6000805160206141d883398151915233612066565b61107260008051602061419883398151915233612066565b61109c7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33612066565b60cb829055801561087e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000808383604051602001611100929190613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff1661117a5760405162461bcd60e51b815260206004820152601f60248201527f536f7572636520636861696e206973206e6f7420696e697469616c697a6564006044820152606401610715565b600090815260c960205260409020549392505050565b61119b600033611281565b6111e75760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401610715565b7f22efc5f993dce37856b77dd72d7d7661032380c9728c4133f3c071c591bc6ca760d2838360405161121b93929190613c32565b60405180910390a160d26107ff828483613d17565b8051600090815260ce6020908152604080832082850151845290915281205461125883612070565b810361126357600191505b50919050565b6000828152609760205260408120610bed908361186c565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6112b78383836120e6565b60006040518060a00160405280858152602001600160c96000888152602001908152602001600020600101546112ed91906139ea565b81523360208201526001600160a01b0385166040820152606001839052805190915061131882612070565b600082815260ce6020908152604080832060d08084528285208054865291845291842094909455848352905281546001929190611356908490613b92565b90915550505050505050565b600060c96000836040516020016113799190613a2c565b60408051601f198184030181529181528151602092830120835290820192909252016000206002015460ff1692915050565b6113c360008051602061419883398151915233611281565b6113df5760405162461bcd60e51b815260040161071590613ac1565b6113ea8160d1610b39565b6114365760405162461bcd60e51b815260206004820181905260248201527f457874726120636f6e7472616374206973206e6f7420726567697374657265646044820152606401610715565b6000805260d16020526114687efa5413e7b01fc543d01f0911de573ace463b956369df4472f39030e8d98b77826121f9565b506040516001600160a01b03821681526000907f4d393b64277bfc0b02e0459a74c316c7f22069352a678319fd8139ba4085e06190602001610bd6565b600081815260976020526040812061067e90611862565b6114d460008051602061419883398151915233611281565b6114f05760405162461bcd60e51b815260040161071590613ac1565b6000826040516020016115039190613a2c565b60405160208183030381529060405280519060200120905060cd54810361153c5760405162461bcd60e51b815260040161071590613dd7565b6107ff818361220e565b60008281526065602052604090206001015461156181611878565b6107ff83836118a7565b60008282604051602001611580929190613b82565b60405160208183030381529060405280519060200120905060cd5481036115e95760405162461bcd60e51b815260206004820152601c60248201527f53636861696e2063616e6e6f7420636f6e6e65637420697473656c66000000006044820152606401610715565b6107ff8161236e565b600054610100900460ff16158080156116125750600054600160ff909116105b8061162c5750303b15801561162c575060005460ff166001145b6116485760405162461bcd60e51b815260040161071590613bbb565b6000805460ff19166001179055801561166b576000805461ff0019166101001790555b611677622dc6c0610fb6565b60cc80546001600160a01b0385166001600160a01b03199091161790556040805160808101825260008082526020808301829052600183850152606083018290529251919260c9926116d791016613585a5b9b995d60ca1b815260070190565b60408051808303601f190181529181528151602092830120835282820193909352908201600020835181558382015160018201558383015160028201805460ff19169115159190911790556060909301516003909301929092555161173e91849101613a2c565b60408051601f19818403018152919052805160209091012060cd5580156107ff576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6117bb60008051602061419883398151915233611281565b6117d75760405162461bcd60e51b815260040161071590613ac1565b6000826040516020016117ea9190613a2c565b60405160208183030381529060405280519060200120905060cd5481036118235760405162461bcd60e51b815260040161071590613dd7565b6107ff8183612462565b60006001600160e01b03198216637965db0b60e01b148061067e57506301ffc9a760e01b6001600160e01b031983161461067e565b600061067e825490565b6000610bed838361250d565b6118828133612537565b50565b61188f828261259b565b60008281526097602052604090206107ff90826119d2565b6118b18282612621565b60008281526097602052604090206107ff90826121f9565b6118e16000805160206141d883398151915233611281565b6118fd5760405162461bcd60e51b815260040161071590613a8c565b6000816040516020016119109190613a2c565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff166119855760405162461bcd60e51b815260206004820152601860248201527710da185a5b881a5cc81b9bdd081a5b9a5d1a585b1a5e995960421b6044820152606401610715565b600090815260c9602052604081208181556001810182905560028101805460ff191690556003015550565b6001600160a01b03811660009081526001830160205260408120541515610bed565b6000610bed836001600160a01b038416612688565b604080518082018252823581526020808401359082015260cc548251632aa77bd360e11b81528351600094610bed949388936080808a013594938a01359360608b0135936001600160a01b03169263554ef7a69260048083019391928290030181865afa158015611a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a809190613e5d565b6126d7565b6000808383604051602001611a9b929190613b82565b60408051808303601f190181528282528051602091820120908301819052908201879052915060009060600160405160208183030381529060405280519060200120905060005b87811015611bf45781898983818110611afd57611afd6139fd565b9050602002810190611b0f9190613ba5565b611b1d906020810190613619565b8a8a84818110611b2f57611b2f6139fd565b9050602002810190611b419190613ba5565b611b52906040810190602001613619565b6040805160208101949094526001600160a01b0392831690840152166060820152608001604051602081830303815290604052898983818110611b9757611b976139fd565b9050602002810190611ba99190613ba5565b611bb7906040810190613ea0565b604051602001611bc993929190613ee6565b6040516020818303038152906040528051906020012091508080611bec90613a13565b915050611ae2565b50979650505050505050565b611c22611c136040840160208501613619565b6001600160a01b03163b151590565b611c9057806000805160206141f8833981519152604051611c839060208082526026908201527f44657374696e6174696f6e20636f6e7472616374206973206e6f74206120636f6040820152651b9d1c9858dd60d21b606082015260800190565b60405180910390a2505050565b611ca06040830160208401613619565b6001600160a01b031663884cee5a60cb5485856000016020810190611cc59190613619565b611cd26040880188613ea0565b6040518663ffffffff1660e01b8152600401611cf19493929190613f0e565b600060405180830381600088803b158015611d0b57600080fd5b5087f193505050508015611d1d575060015b6107ff57611d29613f39565b806308c379a003611d7e5750611d3d613f55565b80611d485750611dd8565b816000805160206141f8833981519152611d638360406128a1565b604051611d7091906136c5565b60405180910390a250505050565b634e487b7103611dd857611d90613fde565b90611d9b5750611dd8565b816000805160206141f883398151915282604051602001611dbe91815260200190565b60408051601f1981840301815290829052611d70916136c5565b3d808015611e02576040519150601f19603f3d011682016040523d82523d6000602084013e611e07565b606091505b50816000805160206141f8833981519152611d638360406128a1565b60003a5a611e319190613ffe565b611e3c903331613b92565b905062695d1f60891b803b15801590611f275750806001600160a01b03166391d14854826001600160a01b031663bc2a1e8d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec1919061401d565b6040516001600160e01b031960e084901b1681526004810191909152306024820152604401602060405180830381865afa158015611f03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f279190614036565b8015611f3a5750670de0b6b3a764000082105b1561087e576000611f5383670de0b6b3a76400006139ea565b9050816001600160a01b031631811015611fcd5760405163204a3e9360e01b8152336004820152602481018290526001600160a01b0383169063204a3e93906044015b600060405180830381600087803b158015611fb057600080fd5b505af1158015611fc4573d6000803e3d6000fd5b50505050505050565b604051630a79309b60e01b81523360048201526001600160a01b03831690630a79309b90602401611f96565b600054610100900460ff166120645760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610715565b565b61087e8282611885565b6000808260000151836020015160001b846040015160601b6bffffffffffffffffffffffff1916856060015160601b6bffffffffffffffffffffffff191686608001516040516020016120c7959493929190614058565b60408051601f1981840301815291905280516020909101209392505050565b600083815260c9602052604090206002015460ff166121175760405162461bcd60e51b815260040161071590613a48565b6121208361296b565b600083815260c96020526040908190206001015490513390829086907f803d7f3ca0e5f93fcce39fa29812ed57a95a151594966e17125220132741c6b09061216b9088908890614093565b60405180910390a4600084815260c96020908152604091829020600301548251848152918201527f64ab4eb9f2b913fd01467c69e91e32483420fab6be93c3a7559adbe1b0356845910160405180910390a1600084815260c9602052604081206001018054916121da83613a13565b9091555050506000928352505060c96020526040902043600390910155565b6000610bed836001600160a01b0384166129dc565b6001600160a01b0381163b6122655760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401610715565b6122818160d15b600085815260209190915260409020906119b0565b1561229e5760405162461bcd60e51b815260040161071590613b0a565b6122a98160d1610b39565b156123125760405162461bcd60e51b815260206004820152603360248201527f457874726120636f6e747261637420697320616c7265616479207265676973746044820152726572656420666f7220616c6c20636861696e7360681b6064820152608401610715565b600082815260d16020526040902061232a90826119d2565b506040516001600160a01b038216815282907f03bcd152926369e3cf05cb7af471a15d680e8ec5d20b13705048d14e94679365906020015b60405180910390a25050565b6123866000805160206141d883398151915233611281565b6123a25760405162461bcd60e51b815260040161071590613a8c565b600081815260c9602052604090206002015460ff16156124045760405162461bcd60e51b815260206004820152601a60248201527f436861696e20697320616c726561647920636f6e6e65637465640000000000006044820152606401610715565b604080516080810182526000808252602080830182815260018486018181526060860185815297855260c99093529490922092518355905192820192909255905160028201805460ff19169115159190911790559051600390910155565b61246d8160d161226c565b6124b95760405162461bcd60e51b815260206004820181905260248201527f457874726120636f6e7472616374206973206e6f7420726567697374657265646044820152606401610715565b600082815260d1602052604090206124d190826121f9565b506040516001600160a01b038216815282907f4d393b64277bfc0b02e0459a74c316c7f22069352a678319fd8139ba4085e06190602001612362565b6000826000018281548110612524576125246139fd565b9060005260206000200154905092915050565b6125418282611281565b61087e57612559816001600160a01b03166014612ad6565b612564836020612ad6565b6040516020016125759291906140b7565b60408051601f198184030181529082905262461bcd60e51b8252610715916004016136c5565b6125a58282611281565b61087e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556125dd3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61262b8282611281565b1561087e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120546126cf5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561067e565b50600061067e565b60006126e287612c71565b6127275760405162461bcd60e51b815260206004820152601660248201527514da59db985d1d5c99481a5cc81b9bdd081d985b1a5960521b6044820152606401610715565b61273386868686612ca7565b61273f57506000612897565b600061274e8860200151612d95565b905061275e886000015182612dba565b61279b5760405162461bcd60e51b815260206004820152600e60248201526d5369676e206e6f7420696e20473160901b6044820152606401610715565b6127a58585612dba565b6127e25760405162461bcd60e51b815260206004820152600e60248201526d48617368206e6f7420696e20473160901b6044820152606401610715565b60006127ec612df0565b90506127f784612eb0565b61283a5760405162461bcd60e51b8152602060048201526014602482015273283ab13634b19025b2bc903737ba1034b710239960611b6044820152606401610715565b6128928960000151838360000151602001518460000151600001518560200151602001518660200151600001518c8c8c60000151602001518d60000151600001518e60200151602001518f6020015160000151612ec4565b925050505b9695505050505050565b60606000835183106128b45783516128b6565b825b90506000816001600160401b038111156128d2576128d26134ec565b6040519080825280601f01601f1916602001820160405280156128fc576020820181803683370190505b50905060005b828110156129625785818151811061291c5761291c6139fd565b602001015160f81c60f81b828281518110612939576129396139fd565b60200101906001600160f81b031916908160001a9053508061295a81613a13565b915050612902565b50949350505050565b612976600033610f25565b8061298657506129868133610f25565b6118825760405162461bcd60e51b815260206004820152602160248201527f53656e64657220636f6e7472616374206973206e6f74207265676973746572656044820152601960fa1b6064820152608401610715565b60008181526001830160205260408120548015612ac5576000612a006001836139ea565b8554909150600090612a14906001906139ea565b9050818114612a79576000866000018281548110612a3457612a346139fd565b9060005260206000200154905080876000018481548110612a5757612a576139fd565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612a8a57612a8a61412c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061067e565b600091505061067e565b5092915050565b60606000612ae5836002613ffe565b612af0906002613b92565b6001600160401b03811115612b0757612b076134ec565b6040519080825280601f01601f191660200182016040528015612b31576020820181803683370190505b509050600360fc1b81600081518110612b4c57612b4c6139fd565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612b7b57612b7b6139fd565b60200101906001600160f81b031916908160001a9053506000612b9f846002613ffe565b612baa906001613b92565b90505b6001811115612c22576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612bde57612bde6139fd565b1a60f81b828281518110612bf457612bf46139fd565b60200101906001600160f81b031916908160001a90535060049490941c93612c1b81614142565b9050612bad565b508315610bed5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610715565b60006000805160206141b8833981519152826000015110801561067e575050602001516000805160206141b88339815191521190565b60006064841115612cba57506000612d8d565b6000612cd46000805160206141b88339815191528761416f565b90506000805160206141b8833981519152612cef8683613b92565b612cf9919061416f565b905060006000805160206141b883398151915260036000805160206141b8833981519152846000805160206141b883398151915286870909089050612d4d60026000805160206141b8833981519152614183565b841080612d6b5750806000805160206141b883398151915285860914155b80612d765750848214155b15612d8657600092505050612d8d565b6001925050505b949350505050565b60006000805160206141b8833981519152612db083826139ea565b61067e919061416f565b60006000805160206141b883398151915280600381868188890909088180612de457612de4614159565b84850914949350505050565b612df861336a565b50604080516080810182527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed8183019081527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26060830152815281518083019092527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa82527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60208381019190915281019190915290565b600061067e82600001518360200151612f94565b600080612ecf6133ae565b8e8152602081018e9052604081018d9052606081018c9052608081018b905260a081018a905260c0810189905260e081018890526101008101879052610120810186905261014081018590526101608101849052612f2b6133cd565b602081610180846008600019fa925082612f7e5760405162461bcd60e51b815260206004820152601460248201527314185a5c9a5b99c818da1958dac819985a5b195960621b6044820152606401610715565b5115159f9e505050505050505050505050505050565b6000612fa08383613068565b15612fad5750600161067e565b6000612fb88361309b565b9050600061304b613028604080518082018252600080825260209182015281518083019092527f2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e582527e9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d29082015290565b61304561303e886130388a61309b565b90613151565b8590613264565b90613264565b805190915015801561305f57506020810151155b95945050505050565b815160009015801561307c57506020830151155b8015613089575081516001145b8015610bed5750506020015115919050565b60408051808201909152600080825260208201526000805160206141b883398151915260008160208501518551099050600082806130db576130db614159565b83806130e9576130e9614159565b84806130f7576130f7614159565b60208801516131076001886139ea565b09875108848061311957613119614159565b60208801518851080990506040518060400160405280828152602001848061314357613143614159565b848508905295945050505050565b604080518082019091526000808252602082015260006000805160206141b8833981519152905060006040518060400160405280838061319357613193614159565b8651885109815260200183806131ab576131ab614159565b86602001518860200151099052905081806131c8576131c8614159565b82806131d6576131d6614159565b60208301516131e66001866139ea565b09825108835281806131fa576131fa614159565b828061320857613208614159565b602083015183510861321a90846139ea565b838061322857613228614159565b848061323657613236614159565b6020880151885108858061324c5761324c614159565b60208a01518a51080908602084015250909392505050565b6040805180820190915260008082526020820152815183516000805160206141b883398151915291116132b557808061329f5761329f614159565b83516132ab90836139ea565b85510882526132ea565b8081806132c4576132c4614159565b85516132d090846139ea565b8551086132dd90836139ea565b6132e7919061416f565b82525b826020015184602001511061332657808061330757613307614159565b602084015161331690836139ea565b8560200151086020830152612acf565b80818061333557613335614159565b602086015161334490846139ea565b85602001510861335490836139ea565b61335e919061416f565b60208301525092915050565b604080516080810182526000918101828152606082019290925290819081526020016133a9604051806040016040528060008152602001600081525090565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b6000602082840312156133fd57600080fd5b81356001600160e01b031981168114610bed57600080fd5b60006020828403121561342757600080fd5b5035919050565b60008060006060848603121561344357600080fd5b505081359360208301359350604090920135919050565b6020808252825182820181905260009190848201906040850190845b8181101561349b5783516001600160a01b031683529284019291840191600101613476565b50909695505050505050565b6001600160a01b038116811461188257600080fd5b600080604083850312156134cf57600080fd5b8235915060208301356134e1816134a7565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60a081018181106001600160401b0382111715613521576135216134ec565b60405250565b604081018181106001600160401b0382111715613521576135216134ec565b601f8201601f191681016001600160401b038111828210171561356b5761356b6134ec565b6040525050565b600082601f83011261358357600080fd5b81356001600160401b0381111561359c5761359c6134ec565b6040516135b3601f8301601f191660200182613546565b8181528460208386010111156135c857600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156135f757600080fd5b81356001600160401b0381111561360d57600080fd5b612d8d84828501613572565b60006020828403121561362b57600080fd5b8135610bed816134a7565b600060a0828403121561126357600080fd5b60008060c0838503121561365b57600080fd5b8235915061366c8460208501613636565b90509250929050565b60005b83811015613690578181015183820152602001613678565b50506000910152565b600081518084526136b1816020860160208601613675565b601f01601f19169290920160200192915050565b602081526000610bed6020830184613699565b60008083601f8401126136ea57600080fd5b5081356001600160401b0381111561370157600080fd5b60208301915083602082850101111561371957600080fd5b9250929050565b600080600080600080610100878903121561373a57600080fd5b86356001600160401b038082111561375157600080fd5b61375d8a838b016136d8565b909850965060208901359550604089013591508082111561377d57600080fd5b818901915089601f83011261379157600080fd5b8135818111156137a057600080fd5b8a60208260051b85010111156137b557600080fd5b6020830195508094505050506137ce8860608901613636565b90509295509295509295565b600080602083850312156137ed57600080fd5b82356001600160401b0381111561380357600080fd5b61380f858286016136d8565b90969095509350505050565b60006020828403121561382d57600080fd5b81356001600160401b038082111561384457600080fd5b9083019060a0828603121561385857600080fd5b60405161386481613502565b82358152602083013560208201526040830135613880816134a7565b60408201526060830135613893816134a7565b60608201526080830135828111156138aa57600080fd5b6138b687828601613572565b60808301525095945050505050565b600080604083850312156138d857600080fd5b50508035926020909101359150565b6000806000606084860312156138fc57600080fd5b83359250602084013561390e816134a7565b915060408401356001600160401b0381111561392957600080fd5b61393586828701613572565b9150509250925092565b6000806040838503121561395257600080fd5b82356001600160401b0381111561396857600080fd5b61397485828601613572565b92505060208301356134e1816134a7565b6000806040838503121561399857600080fd5b82356139a3816134a7565b915060208301356001600160401b038111156139be57600080fd5b6139ca85828601613572565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561067e5761067e6139d4565b634e487b7160e01b600052603260045260246000fd5b600060018201613a2557613a256139d4565b5060010190565b60008251613a3e818460208701613675565b9190910192915050565b60208082526024908201527f44657374696e6174696f6e20636861696e206973206e6f7420696e697469616c6040820152631a5e995960e21b606082015260800190565b6020808252818101527f434841494e5f434f4e4e4543544f525f524f4c45206973207265717569726564604082015260600190565b60208082526029908201527f45585452415f434f4e54524143545f5245474953545241525f524f4c45206973604082015268081c995c5d5a5c995960ba1b606082015260800190565b60208082526024908201527f457874726120636f6e747261637420697320616c726561647920726567697374604082015263195c995960e21b606082015260800190565b600181811c90821680613b6257607f821691505b60208210810361126357634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b8082018082111561067e5761067e6139d4565b60008235605e19833603018112613a3e57600080fd5b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b604081526000808554613c4481613b4e565b8060408601526060600180841660008114613c665760018114613c8057613cb1565b60ff1985168884015283151560051b880183019550613cb1565b8a60005260208060002060005b86811015613ca85781548b8201870152908401908201613c8d565b8a018501975050505b50505050508281036020840152612897818587613c09565b601f8211156107ff57600081815260208120601f850160051c81016020861015613cf05750805b601f850160051c820191505b81811015613d0f57828155600101613cfc565b505050505050565b6001600160401b03831115613d2e57613d2e6134ec565b613d4283613d3c8354613b4e565b83613cc9565b6000601f841160018114613d765760008515613d5e5750838201355b600019600387901b1c1916600186901b178355613dd0565b600083815260209020601f19861690835b82811015613da75786850135825560209485019460019092019101613d87565b5086821015613dc45760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208082526030908201527f44657374696e6174696f6e20636861696e20686173682063616e6e6f7420626560408201526f1032b8bab0b6103a379034ba39b2b63360811b606082015260800190565b600060408284031215613e3957600080fd5b604051613e4581613527565b80915082518152602083015160208201525092915050565b600060808284031215613e6f57600080fd5b604051613e7b81613527565b613e858484613e27565b8152613e948460408501613e27565b60208201529392505050565b6000808335601e19843603018112613eb757600080fd5b8301803591506001600160401b03821115613ed157600080fd5b60200191503681900382131561371957600080fd5b60008451613ef8818460208901613675565b8201838582376000930192835250909392505050565b8481526001600160a01b03841660208201526060604082018190526000906128979083018486613c09565b600060033d1115613f525760046000803e5060005160e01c5b90565b600060443d1015613f635790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715613f9257505050505090565b8285019150815181811115613faa5750505050505090565b843d8701016020828501011115613fc45750505050505090565b613fd360208286010187613546565b509095945050505050565b60008060233d1115613ffa576020600460003e50506000516001905b9091565b6000816000190483118215151615614018576140186139d4565b500290565b60006020828403121561402f57600080fd5b5051919050565b60006020828403121561404857600080fd5b81518015158114610bed57600080fd5b85815284602082015283604082015282606082015260008251614082816080850160208701613675565b919091016080019695505050505050565b6001600160a01b0383168152604060208201819052600090612d8d90830184613699565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516140ef816017850160208801613675565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614120816028840160208801613675565b01602801949350505050565b634e487b7160e01b600052603160045260246000fd5b600081614151576141516139d4565b506000190190565b634e487b7160e01b600052601260045260246000fd5b60008261417e5761417e614159565b500690565b60008261419257614192614159565b50049056fe6155b5aac15ce9aa193c0527a6f43be0a36a7e2e7496c2b615c0e5f92284277330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd472785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e1914b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e59a26469706673582212202d276ec52211cb6b0422d5ff12645bf923438087729432e09c60f0ddc94bf80e64736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.meta.json b/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.meta.json new file mode 100644 index 000000000..839ff7676 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/MessageProxyForSchain.meta.json @@ -0,0 +1,410 @@ +{ + "name": "MessageProxyForSchain", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/Precompiled.dbg.json b/predeployed/src/ima_predeployed/artifacts/Precompiled.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/Precompiled.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/Precompiled.json b/predeployed/src/ima_predeployed/artifacts/Precompiled.json new file mode 100644 index 000000000..d407289d1 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/Precompiled.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "Precompiled", + "sourceName": "contracts/schain/bls/Precompiled.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208fbc5f13d907ef5950d0968cfda0ab45322433a917c3e22da0c4fded49c88c4b64736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208fbc5f13d907ef5950d0968cfda0ab45322433a917c3e22da0c4fded49c88c4b64736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/ProxyAdmin.json b/predeployed/src/ima_predeployed/artifacts/ProxyAdmin.json new file mode 100644 index 000000000..5d642059a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/ProxyAdmin.json @@ -0,0 +1,160 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ProxyAdmin", + "sourceName": "contracts/proxy/ProxyAdmin.sol", + "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 AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "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": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AdminUpgradeabilityProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b61087b8061007d6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461013657806399a88ec4146101f5578063f2fde38b14610230578063f3b7dead146102635761007b565b8063204e1c7a14610080578063715018a6146100cf5780637eff275e146100e65780638da5cb5b14610121575b600080fd5b34801561008c57600080fd5b506100b3600480360360208110156100a357600080fd5b50356001600160a01b0316610296565b604080516001600160a01b039092168252519081900360200190f35b3480156100db57600080fd5b506100e4610328565b005b3480156100f257600080fd5b506100e46004803603604081101561010957600080fd5b506001600160a01b03813581169160200135166103d4565b34801561012d57600080fd5b506100b36104a1565b6100e46004803603606081101561014c57600080fd5b6001600160a01b03823581169260208101359091169181019060608101604082013564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506104b0945050505050565b34801561020157600080fd5b506100e46004803603604081101561021857600080fd5b506001600160a01b03813581169160200135166105e9565b34801561023c57600080fd5b506100e46004803603602081101561025357600080fd5b50356001600160a01b031661069a565b34801561026f57600080fd5b506100b36004803603602081101561028657600080fd5b50356001600160a01b031661079c565b6000806060836001600160a01b03166040518080635c60da1b60e01b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b606091505b50915091508161030957600080fd5b80806020019051602081101561031e57600080fd5b5051949350505050565b6103306107fb565b6001600160a01b03166103416104a1565b6001600160a01b03161461038a576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6103dc6107fb565b6001600160a01b03166103ed6104a1565b6001600160a01b031614610436576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316638f283970826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b6104b86107fb565b6001600160a01b03166104c96104a1565b6001600160a01b031614610512576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b826001600160a01b0316634f1ef2863484846040518463ffffffff1660e01b815260040180836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561057f578181015183820152602001610567565b50505050905090810190601f1680156105ac5780820380516001836020036101000a031916815260200191505b5093505050506000604051808303818588803b1580156105cb57600080fd5b505af11580156105df573d6000803e3d6000fd5b5050505050505050565b6105f16107fb565b6001600160a01b03166106026104a1565b6001600160a01b03161461064b576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316633659cfe6826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b6106a26107fb565b6001600160a01b03166106b36104a1565b6001600160a01b0316146106fc576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b6001600160a01b0381166107415760405162461bcd60e51b81526004018080602001828103825260268152602001806108006026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806060836001600160a01b031660405180806303e1469160e61b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212203768212fc739b6f5d04031f3515c4811eaf8dd5225cdb7a15a3d7fa534d1ba9364736f6c634300060c0033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461013657806399a88ec4146101f5578063f2fde38b14610230578063f3b7dead146102635761007b565b8063204e1c7a14610080578063715018a6146100cf5780637eff275e146100e65780638da5cb5b14610121575b600080fd5b34801561008c57600080fd5b506100b3600480360360208110156100a357600080fd5b50356001600160a01b0316610296565b604080516001600160a01b039092168252519081900360200190f35b3480156100db57600080fd5b506100e4610328565b005b3480156100f257600080fd5b506100e46004803603604081101561010957600080fd5b506001600160a01b03813581169160200135166103d4565b34801561012d57600080fd5b506100b36104a1565b6100e46004803603606081101561014c57600080fd5b6001600160a01b03823581169260208101359091169181019060608101604082013564010000000081111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460018302840111640100000000831117156101b457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506104b0945050505050565b34801561020157600080fd5b506100e46004803603604081101561021857600080fd5b506001600160a01b03813581169160200135166105e9565b34801561023c57600080fd5b506100e46004803603602081101561025357600080fd5b50356001600160a01b031661069a565b34801561026f57600080fd5b506100b36004803603602081101561028657600080fd5b50356001600160a01b031661079c565b6000806060836001600160a01b03166040518080635c60da1b60e01b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b606091505b50915091508161030957600080fd5b80806020019051602081101561031e57600080fd5b5051949350505050565b6103306107fb565b6001600160a01b03166103416104a1565b6001600160a01b03161461038a576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6103dc6107fb565b6001600160a01b03166103ed6104a1565b6001600160a01b031614610436576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316638f283970826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031690565b6104b86107fb565b6001600160a01b03166104c96104a1565b6001600160a01b031614610512576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b826001600160a01b0316634f1ef2863484846040518463ffffffff1660e01b815260040180836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561057f578181015183820152602001610567565b50505050905090810190601f1680156105ac5780820380516001836020036101000a031916815260200191505b5093505050506000604051808303818588803b1580156105cb57600080fd5b505af11580156105df573d6000803e3d6000fd5b5050505050505050565b6105f16107fb565b6001600160a01b03166106026104a1565b6001600160a01b03161461064b576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b816001600160a01b0316633659cfe6826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561048557600080fd5b6106a26107fb565b6001600160a01b03166106b36104a1565b6001600160a01b0316146106fc576040805162461bcd60e51b81526020600482018190526024820152600080516020610826833981519152604482015290519081900360640190fd5b6001600160a01b0381166107415760405162461bcd60e51b81526004018080602001828103825260268152602001806108006026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806060836001600160a01b031660405180806303e1469160e61b8152506004019050600060405180830381855afa9150503d80600081146102f5576040519150601f19603f3d011682016040523d82523d6000602084013e6102fa565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212203768212fc739b6f5d04031f3515c4811eaf8dd5225cdb7a15a3d7fa534d1ba9364736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/SkaleVerifier.dbg.json b/predeployed/src/ima_predeployed/artifacts/SkaleVerifier.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/SkaleVerifier.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/SkaleVerifier.json b/predeployed/src/ima_predeployed/artifacts/SkaleVerifier.json new file mode 100644 index 000000000..665660707 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/SkaleVerifier.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "SkaleVerifier", + "sourceName": "contracts/schain/bls/SkaleVerifier.sol", + "abi": [], + "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a9431b36756d95801dab0d23c28055d28c6fa6ee04daf2ade85bf5d5ae5a13c364736f6c634300060c0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a9431b36756d95801dab0d23c28055d28c6fa6ee04daf2ade85bf5d5ae5a13c364736f6c634300060c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManager.dbg.json b/predeployed/src/ima_predeployed/artifacts/TokenManager.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManager.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManager.json b/predeployed/src/ima_predeployed/artifacts/TokenManager.json new file mode 100644 index 000000000..5aa9bd80b --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManager.json @@ -0,0 +1,572 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManager", + "sourceName": "contracts/schain/TokenManager.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldValue", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "DepositBoxWasChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract ICommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "schainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract ITokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManager.meta.json b/predeployed/src/ima_predeployed/artifacts/TokenManager.meta.json new file mode 100644 index 000000000..8369ed1c2 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManager.meta.json @@ -0,0 +1,410 @@ +{ + "name": "TokenManager", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.dbg.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.json new file mode 100644 index 000000000..bcad7da39 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.json @@ -0,0 +1,1017 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerERC1155", + "sourceName": "contracts/schain/TokenManagers/TokenManagerERC1155.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldValue", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "DepositBoxWasChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnSchain", + "type": "address" + } + ], + "name": "ERC1155TokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnSchain", + "type": "address" + } + ], + "name": "ERC1155TokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "ERC1155TokenReady", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc1155OnSchain", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "ERC1155TokenReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetChainName", + "type": "string" + }, + { + "internalType": "address", + "name": "erc1155OnMainnet", + "type": "address" + }, + { + "internalType": "address", + "name": "erc1155OnSchain", + "type": "address" + } + ], + "name": "addERC1155TokenByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC1155OnChain", + "name": "", + "type": "address" + } + ], + "name": "addedClones", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "clonesErc1155", + "outputs": [ + { + "internalType": "contract ERC1155OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract ICommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deprecatedClonesErc1155", + "outputs": [ + { + "internalType": "contract ERC1155OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exitToMainERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "exitToMainERC1155Batch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract ITokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferToSchainERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "transferToSchainERC1155Batch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transferredAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5061839180620000216000396000f3fe60806040523480156200001157600080fd5b5060043610620002795760003560e01c80636d6c68e61162000155578063c5d7666411620000c7578063dec2deb61162000086578063dec2deb6146200064e578063e3e50fa41462000663578063edcc12b5146200068f578063f23a6e6114620006a6578063f5b52e1f14620006bd57600080fd5b8063c5d7666414620005ca578063ca15c87314620005e1578063cb703bff14620005f8578063cc5b715b146200060f578063d547741f146200063757600080fd5b8063a217fddf1162000114578063a217fddf1462000549578063aebaaca91462000552578063b9581c501462000578578063bc197c811462000582578063c0e312dc14620005b357600080fd5b80636d6c68e614620004d95780638369091714620004ed578063884cee5a14620005045780639010d07c146200051b57806391d14854146200053257600080fd5b80632f2ff15d11620001ef57806350f4428011620001ae57806350f44280146200044d5780635573b8b6146200048357806357157cd914620004975780636ce681d214620004ae5780636d61128614620004c557600080fd5b80632f2ff15d14620003e757806336568abe14620003fe57806339927cf914620004155780633b690b6b146200042c5780633fa194ce146200043657600080fd5b806315ecfe5e116200023c57806315ecfe5e1462000355578063248a9ca3146200038c57806328c5e18214620003b25780632d32926214620003bc5780632dc151de14620003d357600080fd5b806301ffc9a7146200027e578063029996b814620002aa5780630b885ac314620002b65780630f1a8f7414620002cd5780631420de3f1462000312575b600080fd5b620002956200028f36600462003fd6565b620006d4565b60405190151581526020015b60405180910390f35b620002b462000702565b005b620002b4620002c73660046200415c565b6200075a565b620002f9620002de366004620041f1565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001620002a1565b62000346620003233660046200420b565b60d260209081526000938452604080852082529284528284209052825290205481565b604051908152602001620002a1565b620002f96200036636600462004246565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b620003466200039d366004620041f1565b60009081526065602052604090206001015490565b6200034662000839565b620002b4620003cd366004620042c4565b62000884565b60ca54620002f9906001600160a01b031681565b620002b4620003f836600462004246565b62000aa0565b620002b46200040f36600462004246565b62000ace565b620002956200042636600462004330565b62000b50565b6200034660cc5481565b620003466000805160206200833c83398151915281565b620004746040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002a19190620043c9565b60c954620002f9906001600160a01b031681565b620002b4620004a836600462004425565b62000bad565b620002b4620004bf3660046200415c565b62000dcd565b60cd54620002f9906001600160a01b031681565b60cb54620002f9906001600160a01b031681565b620002b4620004fe366004620044df565b62000ff0565b620002b4620005153660046200456a565b6200110e565b620002f96200052c366004620045cb565b620012d0565b620002956200054336600462004246565b620012f1565b62000346600081565b6200029562000563366004620045ee565b60d06020526000908152604090205460ff1681565b620002b46200131c565b62000599620005933660046200460e565b62001365565b6040516001600160e01b03199091168152602001620002a1565b620002b4620005c436600462004330565b620013ef565b620002b4620005db366004620046da565b6200150d565b62000346620005f2366004620041f1565b62001826565b620002b46200060936600462004749565b6200183f565b620003467ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b620002b46200064836600462004246565b62001997565b60cd546200029590600160a01b900460ff1681565b620002f962000674366004620045ee565b60cf602052600090815260409020546001600160a01b031681565b620002b4620006a0366004620045ee565b620019c0565b62000599620006b7366004620047a5565b62001adc565b620002b4620006ce36600462004828565b62001b64565b60006001600160e01b0319821663112fc36360e01b1480620006fc5750620006fc8262001c79565b92915050565b6200071d6000805160206200833c83398151915233620012f1565b620007455760405162461bcd60e51b81526004016200073c9062004860565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b600054610100900460ff16158080156200077b5750600054600160ff909116105b80620007975750303b15801562000797575060005460ff166001145b620007b65760405162461bcd60e51b81526004016200073c90620048a1565b6000805460ff191660011790558015620007da576000805461ff0019166101001790555b620007e9868686868662000dcd565b801562000831576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200086b9190620048ef565b6040516020818303038152906040528051906020012081565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051339450909250620008d091508490602001620048ef565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000912929101620048ef565b604051602081830303815290604052805190602001208103620009495760405162461bcd60e51b81526004016200073c906200490d565b6001600160a01b038216620009a15760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374207265636569766572206164647265737300000000000060448201526064016200073c565b600081815260ce60205260409020546001600160a01b0316620009d85760405162461bcd60e51b81526004016200073c906200495d565b60008888604051602001620009ef92919062004994565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000a5357600080fd5b505af115801562000a68573d6000803e3d6000fd5b505050600082815260ce602052604090205462000a95915082906001600160a01b031689338a8a62001ca1565b505050505050505050565b60008281526065602052604090206001015462000abd8162002020565b62000ac983836200202f565b505050565b6001600160a01b038116331462000b405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016200073c565b62000b4c828262002055565b5050565b6000806001600160a01b031660ce6000858560405160200162000b7592919062004994565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060405133945090925062000bf991508490602001620048ef565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000c3b929101620048ef565b60405160208183030381529060405280519060200120810362000c725760405162461bcd60e51b81526004016200073c906200490d565b6001600160a01b03821662000cca5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374207265636569766572206164647265737300000000000060448201526064016200073c565b600081815260ce60205260409020546001600160a01b031662000d015760405162461bcd60e51b81526004016200073c906200495d565b60008a8a60405160200162000d1892919062004994565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000d7c57600080fd5b505af115801562000d91573d6000803e3d6000fd5b505050600082815260ce602052604090205462000dc0915082906001600160a01b03168b338c8c8c8c6200207b565b5050505050505050505050565b600054610100900460ff161580801562000dee5750600054600160ff909116105b8062000e0a5750303b15801562000e0a575060005460ff166001145b62000e295760405162461bcd60e51b81526004016200073c90620048a1565b6000805460ff19166001179055801562000e4d576000805461ff0019166101001790555b6001600160a01b03821662000ea55760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f2062652073657460448201526064016200073c565b62000eaf620024b5565b62000ebc60003362002524565b62000ed76000805160206200833c8339815191523362002524565b62000f037ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362002524565b8560405160200162000f169190620048ef565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562000831576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200162000828565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929262001035929101620048ef565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b1580156200108857600080fd5b505af11580156200109d573d6000803e3d6000fd5b50505050620011076040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620010d79190620048ef565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168733888888886200207b565b5050505050565b60c9546001600160a01b031633146200116a5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f78790000000060448201526064016200073c565b838360cc54821415801562001186575062001186828262002530565b620011d45760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f7272656374000000000060448201526064016200073c565b6000620011e28585620025bb565b90506000600982600e811115620011fd57620011fd620049a4565b14806200121e5750600a82600e8111156200121c576200121c620049a4565b145b1562001239576200123188878762002612565b9050620012c6565b600b82600e811115620012505762001250620049a4565b1480620012715750600c82600e8111156200126f576200126f620049a4565b145b1562001284576200123188878762002abc565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b60448201526064016200073c565b5050505050505050565b6000828152609760205260408120620012ea908362002f01565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b620013376000805160206200833c83398151915233620012f1565b620013565760405162461bcd60e51b81526004016200073c9062004860565b60cd805460ff60a01b19169055565b60006001600160a01b0389163014620013c15760405162461bcd60e51b815260206004820152601d60248201527f5265766572742045524331313535206261746368207472616e7366657200000060448201526064016200073c565b507fbc197c819b3e337a6f9652dd10becd7eef83032af3b9d958d3d42f669414662198975050505050505050565b60ca546001600160a01b031633148062001411575062001411600033620012f1565b620014575760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b60448201526064016200073c565b600082826040516020016200146e92919062004994565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316620014ed5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f7420736574000000000000000060448201526064016200073c565b600090815260ce6020526040902080546001600160a01b03191690555050565b620015397ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012f1565b620015875760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c4520697320726571756972656460448201526064016200073c565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa90620015bb9087908790600401620049ba565b602060405180830381865afa158015620015d9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015ff9190620049e9565b620016465760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b60448201526064016200073c565b6001600160a01b0381163b6200169f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e74726163740060448201526064016200073c565b60008484604051602001620016b692919062004994565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b0388811683529452919091205490925016156200173a5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b60448201526064016200073c565b6001600160a01b038216600090815260d0602052604090205460ff1615620017a55760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c726561647920616464656400000000000000000060448201526064016200073c565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917ff86f4b9b158b421a62f31d8b430c86afba56c6bb611fb82bc115dd030903d36a91a45050505050565b6000818152609760205260408120620006fc9062002f0f565b60ca546001600160a01b031633148062001861575062001861600033620012f1565b620018a75760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b60448201526064016200073c565b60008383604051602001620018be92919062004994565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316156200193e5760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c7265616479207365740000000060448201526064016200073c565b6001600160a01b038216620019675760405162461bcd60e51b81526004016200073c906200495d565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b600082815260656020526040902060010154620019b48162002020565b62000ac9838362002055565b620019cd600033620012f1565b62001a1b5760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c45206973207265717569726564000060448201526064016200073c565b6001600160a01b03811662001a735760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f2062652073657460448201526064016200073c565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038716301462001b385760405162461bcd60e51b815260206004820152601760248201527f5265766572742045524331313535207472616e7366657200000000000000000060448201526064016200073c565b507ff23a6e612e1ff4830e658fe43f4e3cb4a5f8170bd5d9e69fb5d7a7fa9e4fdf979695505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929262001ba9929101620048ef565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b15801562001bfc57600080fd5b505af115801562001c11573d6000803e3d6000fd5b5050505062000ac96040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001c4b9190620048ef565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168533868662001ca1565b60006001600160e01b03198216630271189760e51b1480620006fc5750620006fc8262002f1a565b600086815260d1602090815260408083206001600160a01b0380891685529252822054168062001d0f57506001600160a01b038516600090815260d06020526040902054859060ff161562001d0a5760405162461bcd60e51b81526004016200073c9062004a0d565b600191505b6001600160a01b0381163b62001d635760405162461bcd60e51b81526020600482015260186024820152772737903a37b5b2b71031b637b7329037b71039b1b430b4b760411b60448201526064016200073c565b60405163e985e9c560e01b81523360048201523060248201526001600160a01b0382169063e985e9c590604401602060405180830381865afa15801562001dae573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001dd49190620049e9565b62001e1e5760405162461bcd60e51b81526020600482015260196024820152782737ba1030b63637bbb2b21022a92198989a9a902a37b5b2b760391b60448201526064016200073c565b600062001e2e8787878762002f42565b9050821562001f41576040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001e699190620048ef565b60405160208183030381529060405280519060200120890362001ea05760405162461bcd60e51b81526004016200073c9062004a44565b62001eaf898333888862002fab565b905062001ed3898362001ec28862003073565b62001ecd8862003073565b620030bd565b604051637921219560e11b81526001600160a01b0383169063f242432a9062001f0790339030908a908a9060040162004a97565b600060405180830381600087803b15801562001f2257600080fd5b505af115801562001f37573d6000803e3d6000fd5b5050505062001fab565b604051637a94c56560e11b815233600482015260248101869052604481018590526001600160a01b0383169063f5298aca90606401600060405180830381600087803b15801562001f9157600080fd5b505af115801562001fa6573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001fe1908c908c90869060040162004acf565b600060405180830381600087803b15801562001ffc57600080fd5b505af115801562002011573d6000803e3d6000fd5b50505050505050505050505050565b6200202c8133620031c9565b50565b6200203b828262003238565b600082815260976020526040902062000ac99082620032c2565b620020618282620032d9565b600082815260976020526040902062000ac9908262003343565b600088815260d1602090815260408083206001600160a01b03808b16855292528220541680620020e957506001600160a01b038716600090815260d06020526040902054879060ff1615620020e45760405162461bcd60e51b81526004016200073c9062004a0d565b600191505b6001600160a01b0381163b6200213d5760405162461bcd60e51b81526020600482015260186024820152772737903a37b5b2b71031b637b7329037b71039b1b430b4b760411b60448201526064016200073c565b60405163e985e9c560e01b81523360048201523060248201526001600160a01b0382169063e985e9c590604401602060405180830381865afa15801562002188573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620021ae9190620049e9565b620021f85760405162461bcd60e51b81526020600482015260196024820152782737ba1030b63637bbb2b21022a92198989a9a902a37b5b2b760391b60448201526064016200073c565b60006200226b898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b9182918501908490808284376000920191909152506200335a92505050565b90508215620023d3576040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620022a69190620048ef565b604051602081830303815290604052805190602001208b03620022dd5760405162461bcd60e51b81526004016200073c9062004a44565b620022ee8b83338a8a8a8a620033a9565b9050620023618b8389898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b918291850190849080828437600092019190915250620030bd92505050565b604051631759616b60e11b81526001600160a01b03831690632eb2c2d6906200239990339030908c908c908c908c9060040162004b37565b600060405180830381600087803b158015620023b457600080fd5b505af1158015620023c9573d6000803e3d6000fd5b505050506200243e565b604051631ac8311560e21b81526001600160a01b03831690636b20c45490620024099033908b908b908b908b9060040162004b9a565b600060405180830381600087803b1580156200242457600080fd5b505af115801562002439573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062002474908e908e90869060040162004acf565b600060405180830381600087803b1580156200248f57600080fd5b505af1158015620024a4573d6000803e3d6000fd5b505050505050505050505050505050565b600054610100900460ff16620025225760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200073c565b565b62000b4c82826200202f565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620025649190620048ef565b604051602081830303815290604052805190602001208314620025a457600083815260ce60205260409020546001600160a01b03838116911614620012ea565b5060cd546001600160a01b03908116911614919050565b600080620025cc83850185620041f1565b9050620025db60208262004be2565b6000036200260457620025fb620025f58483818862004c05565b620025bb565b915050620006fc565b620025fb8385018562004c46565b600080620026218484620025bb565b9050600080808080600986600e811115620026405762002640620049a4565b03620026c5576000620026548a8a6200352b565b90508060400151955080602001519450806060015193508060800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002882565b6000620026d38a8a620035e7565b9050806000015160400151955080600001516020015194508060000151606001519350806000015160800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b031603620028805760cd54600160a01b900460ff16620027c35760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c65640000000060448201526064016200073c565b602081015151604051620027d79062003f30565b620027e39190620043c9565b604051809103906000f08015801562002800573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918e917fae5aabebaedd1b95e68d95d1bc05734a63a8e451f94b37864515b78c532247d99190a45b505b600986600e811115620028995762002899620049a4565b148015620028ee57506040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620028d49190620048ef565b604051602081830303815290604052805190602001208a14155b801562002910575060008a815260d36020526040902062002910908562003689565b15620029d0576001600160a01b0384163b620029405760405162461bcd60e51b81526004016200073c9062004a0d565b620029628a85620029518662003073565b6200295c8662003073565b620036ac565b604051637921219560e11b81526001600160a01b0385169063f242432a906200299690309089908890889060040162004a97565b600060405180830381600087803b158015620029b157600080fd5b505af1158015620029c6573d6000803e3d6000fd5b5050505062002a4a565b60405163731133e960e01b81526001600160a01b0386811660048301526024820185905260448201849052608060648301526000608483015282169063731133e99060a401600060405180830381600087803b15801562002a3057600080fd5b505af115801562002a45573d6000803e3d6000fd5b505050505b806001600160a01b0316846001600160a01b03168b7f2349a6dafaf84dd371a44cd78bd587d9e750c3dfa1137d21f34f00e0d4babcb262002a8b8762003073565b62002a968762003073565b60405162002aa692919062004ca1565b60405180910390a4509298975050505050505050565b60008062002acb8484620025bb565b905060008060608082600b86600e81111562002aeb5762002aeb620049a4565b0362002b7057600062002aff8a8a620037b8565b90508060400151955080602001519450806060015193508060800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002d18565b600062002b7e8a8a62003879565b9050806000015160400151955080600001516020015194508060000151606001519350806000015160800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b03160362002d165760cd54600160a01b900460ff1662002c6e5760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c65640000000060448201526064016200073c565b60208101515160405162002c829062003f30565b62002c8e9190620043c9565b604051809103906000f08015801562002cab573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a81168086529190935281842080546001600160a01b03191693861693841790559051939550909290918e917fae5aabebaedd1b95e68d95d1bc05734a63a8e451f94b37864515b78c532247d99190a45b505b600b86600e81111562002d2f5762002d2f620049a4565b14801562002d8457506040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162002d6a9190620048ef565b604051602081830303815290604052805190602001208a14155b801562002da6575060008a815260d36020526040902062002da6908562003689565b1562002e52576001600160a01b0384163b62002dd65760405162461bcd60e51b81526004016200073c9062004a0d565b62002de48a858585620036ac565b604051631759616b60e11b81526001600160a01b03851690632eb2c2d69062002e1890309089908890889060040162004cca565b600060405180830381600087803b15801562002e3357600080fd5b505af115801562002e48573d6000803e3d6000fd5b5050505062002eb9565b604051630fbfeffd60e11b81526001600160a01b03821690631f7fdffa9062002e849088908790879060040162004d29565b600060405180830381600087803b15801562002e9f57600080fd5b505af115801562002eb4573d6000803e3d6000fd5b505050505b806001600160a01b0316846001600160a01b03168b7f2349a6dafaf84dd371a44cd78bd587d9e750c3dfa1137d21f34f00e0d4babcb2868660405162002aa692919062004ca1565b6000620012ea838362003920565b6000620006fc825490565b60006001600160e01b03198216635a05180f60e01b1480620006fc5750620006fc826200394d565b6040805160c081018252600960a0820190815281526001600160a01b0380871660208084019190915290861682840152606080830186905260808301859052925162002f919183910162004ded565b604051602081830303815290604052915050949350505050565b600085815260d3602052604081206060919062002fc9908762003689565b90508062002ffe5762002fdd878762003984565b62002ff68686868662002ff08b62003a9d565b62003b2e565b91506200300f565b6200300c8686868662002f42565b91505b856001600160a01b0316877f601046fc8dbb772c2b88d30850532ffec5253f2e73c855af1c5f318a7a4562b0620030468762003073565b620030518762003073565b6040516200306192919062004ca1565b60405180910390a35095945050505050565b604080516001808252818301909252606091602080830190803683370190505090508181600081518110620030ac57620030ac62004dfd565b602002602001018181525050919050565b8051825114620031105760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206c656e677468206f662061727261797300000000000060448201526064016200073c565b60005b8251811015620011075781818151811062003132576200313262004dfd565b602002602001015160d260008781526020019081526020016000206000866001600160a01b03166001600160a01b03168152602001908152602001600020600085848151811062003187576200318762004dfd565b602002602001015181526020019081526020016000206000828254620031ae919062004e29565b90915550819050620031c08162004e3f565b91505062003113565b620031d58282620012f1565b62000b4c57620031f0816001600160a01b0316601462003bb5565b620031fd83602062003bb5565b6040516020016200321092919062004e5b565b60408051601f198184030181529082905262461bcd60e51b82526200073c91600401620043c9565b620032448282620012f1565b62000b4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200327e3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012ea836001600160a01b03841662003d6e565b620032e58282620012f1565b1562000b4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012ea836001600160a01b03841662003dc0565b6040805160c081018252600b60a0820190815281526001600160a01b0380871660208084019190915290861682840152606080830186905260808301859052925162002f919183910162004f3b565b600087815260d36020526040812060609190620033c7908962003689565b9050806200346157620033db898962003984565b62003459888888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152506200345392508f915062003a9d9050565b62003ec4565b9150620034d5565b620034d2888888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152506200335a92505050565b91505b876001600160a01b0316897f601046fc8dbb772c2b88d30850532ffec5253f2e73c855af1c5f318a7a4562b08888888860405162003517949392919062004f50565b60405180910390a350979650505050505050565b6040805160c081018252600060a0820181815282526020820181905291810182905260608101829052608081019190915260096200356a8484620025bb565b600e8111156200357e576200357e620049a4565b14620035d95760405162461bcd60e51b8152602060048201526024808201527f4d6573736167652074797065206973206e6f742045524331313535207472616e60448201526339b332b960e11b60648201526084016200073c565b620012ea828401846200502b565b620035f162003f3e565b600a620035ff8484620025bb565b600e811115620036135762003613620049a4565b146200367b5760405162461bcd60e51b815260206004820152603060248201527f4d6573736167652074797065206973206e6f742045524331313535416e64546f60448201526f35b2b724b73337903a3930b739b332b960811b60648201526084016200073c565b620012ea8284018462005097565b6001600160a01b03811660009081526001830160205260408120541515620012ea565b8051825114620036ff5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206c656e677468206f662061727261797300000000000060448201526064016200073c565b60005b8251811015620011075781818151811062003721576200372162004dfd565b602002602001015160d260008781526020019081526020016000206000866001600160a01b03166001600160a01b03168152602001908152602001600020600085848151811062003776576200377662004dfd565b6020026020010151815260200190815260200160002060008282546200379d91906200511f565b90915550819050620037af8162004e3f565b91505062003702565b6040805160c081018252600060a082018181528252602082018190529181019190915260608082018190526080820152600b620037f68484620025bb565b600e8111156200380a576200380a620049a4565b146200386b5760405162461bcd60e51b815260206004820152602960248201527f4d6573736167652074797065206973206e6f7420455243313135354261746368604482015268103a3930b739b332b960b91b60648201526084016200073c565b620012ea8284018462005267565b6200388362003f97565b600c620038918484620025bb565b600e811115620038a557620038a5620049a4565b14620039125760405162461bcd60e51b815260206004820152603560248201527f4d6573736167652074797065206973206e6f742045524331313535426174636860448201527420b7322a37b5b2b724b73337903a3930b739b332b960591b60648201526084016200073c565b620012ea82840184620052a7565b60008260000182815481106200393a576200393a62004dfd565b9060005260206000200154905092915050565b60006001600160e01b03198216637965db0b60e01b1480620006fc57506301ffc9a760e01b6001600160e01b0319831614620006fc565b6001600160a01b0381163b620039dd5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e74726163740060448201526064016200073c565b600082815260d360205260409020620039f7908262003689565b1562003a465760405162461bcd60e51b815260206004820152601f60248201527f4552433131353520546f6b656e2077617320616c72656164792061646465640060448201526064016200073c565b600082815260d36020526040902062003a609082620032c2565b506040516000906001600160a01b0383169084907ff86f4b9b158b421a62f31d8b430c86afba56c6bb611fb82bc115dd030903d36a908490a45050565b6040805160208101909152606081526040805160208101918290526303a24d0760e21b90915260006024820152806001600160a01b038416630e89341c60448301600060405180830381865afa15801562003afc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262003b26919081019062005325565b905292915050565b604080516101008101825260609160009190819081018060e0830180600a81525081526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018781525081526020018481525090508060405160200162003b9a91906200539b565b60405160208183030381529060405291505095945050505050565b6060600062003bc6836002620053d7565b62003bd390600262004e29565b6001600160401b0381111562003bed5762003bed62004002565b6040519080825280601f01601f19166020018201604052801562003c18576020820181803683370190505b509050600360fc1b8160008151811062003c365762003c3662004dfd565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062003c685762003c6862004dfd565b60200101906001600160f81b031916908160001a905350600062003c8e846002620053d7565b62003c9b90600162004e29565b90505b600181111562003d1d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062003cd35762003cd362004dfd565b1a60f81b82828151811062003cec5762003cec62004dfd565b60200101906001600160f81b031916908160001a90535060049490941c9362003d1581620053f9565b905062003c9e565b508315620012ea5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016200073c565b600081815260018301602052604081205462003db757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620006fc565b506000620006fc565b6000818152600183016020526040812054801562003eb957600062003de76001836200511f565b855490915060009062003dfd906001906200511f565b905081811462003e6957600086600001828154811062003e215762003e2162004dfd565b906000526020600020015490508087600001848154811062003e475762003e4762004dfd565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003e7d5762003e7d62005413565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620006fc565b6000915050620006fc565b604080516101008101825260609160009190819081018060e0830180600c81525081526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018781525081526020018481525090508060405160200162003b9a919062005429565b612ecd806200546f83390190565b6040805161010081018252600060e08201818152928201928352606082018190526080820181905260a0820181905260c08201529081905b815260200162003f926040518060200160405280606081525090565b905290565b6040805161010081018252600060e082018181529282019283526060808301829052608083019190915260a0820181905260c082015290819062003f76565b60006020828403121562003fe957600080fd5b81356001600160e01b031981168114620012ea57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051602081016001600160401b03811182821017156200403d576200403d62004002565b60405290565b60405160a081016001600160401b03811182821017156200403d576200403d62004002565b604080519081016001600160401b03811182821017156200403d576200403d62004002565b604051601f8201601f191681016001600160401b0381118282101715620040b857620040b862004002565b604052919050565b60006001600160401b03821115620040dc57620040dc62004002565b50601f01601f191660200190565b600082601f830112620040fc57600080fd5b8135620041136200410d82620040c0565b6200408d565b8181528460208386010111156200412957600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b03811681146200202c57600080fd5b600080600080600060a086880312156200417557600080fd5b85356001600160401b038111156200418c57600080fd5b6200419a88828901620040ea565b9550506020860135620041ad8162004146565b93506040860135620041bf8162004146565b92506060860135620041d18162004146565b91506080860135620041e38162004146565b809150509295509295909350565b6000602082840312156200420457600080fd5b5035919050565b6000806000606084860312156200422157600080fd5b833592506020840135620042358162004146565b929592945050506040919091013590565b600080604083850312156200425a57600080fd5b8235915060208301356200426e8162004146565b809150509250929050565b60008083601f8401126200428c57600080fd5b5081356001600160401b03811115620042a457600080fd5b602083019150836020828501011115620042bd57600080fd5b9250929050565b600080600080600060808688031215620042dd57600080fd5b85356001600160401b03811115620042f457600080fd5b620043028882890162004279565b9096509450506020860135620043188162004146565b94979396509394604081013594506060013592915050565b600080602083850312156200434457600080fd5b82356001600160401b038111156200435b57600080fd5b620043698582860162004279565b90969095509350505050565b60005b838110156200439257818101518382015260200162004378565b50506000910152565b60008151808452620043b581602086016020860162004375565b601f01601f19169290920160200192915050565b602081526000620012ea60208301846200439b565b60008083601f840112620043f157600080fd5b5081356001600160401b038111156200440957600080fd5b6020830191508360208260051b8501011115620042bd57600080fd5b60008060008060008060006080888a0312156200444157600080fd5b87356001600160401b03808211156200445957600080fd5b620044678b838c0162004279565b909950975060208a013591506200447e8262004146565b909550604089013590808211156200449557600080fd5b620044a38b838c01620043de565b909650945060608a0135915080821115620044bd57600080fd5b50620044cc8a828b01620043de565b989b979a50959850939692959293505050565b600080600080600060608688031215620044f857600080fd5b8535620045058162004146565b945060208601356001600160401b03808211156200452257600080fd5b6200453089838a01620043de565b909650945060408801359150808211156200454a57600080fd5b506200455988828901620043de565b969995985093965092949392505050565b600080600080606085870312156200458157600080fd5b843593506020850135620045958162004146565b925060408501356001600160401b03811115620045b157600080fd5b620045bf8782880162004279565b95989497509550505050565b60008060408385031215620045df57600080fd5b50508035926020909101359150565b6000602082840312156200460157600080fd5b8135620012ea8162004146565b60008060008060008060008060a0898b0312156200462b57600080fd5b8835620046388162004146565b975060208901356200464a8162004146565b965060408901356001600160401b03808211156200466757600080fd5b620046758c838d01620043de565b909850965060608b01359150808211156200468f57600080fd5b6200469d8c838d01620043de565b909650945060808b0135915080821115620046b757600080fd5b50620046c68b828c0162004279565b999c989b5096995094979396929594505050565b60008060008060608587031215620046f157600080fd5b84356001600160401b038111156200470857600080fd5b620047168782880162004279565b90955093505060208501356200472c8162004146565b915060408501356200473e8162004146565b939692955090935050565b6000806000604084860312156200475f57600080fd5b83356001600160401b038111156200477657600080fd5b620047848682870162004279565b90945092505060208401356200479a8162004146565b809150509250925092565b60008060008060008060a08789031215620047bf57600080fd5b8635620047cc8162004146565b95506020870135620047de8162004146565b9450604087013593506060870135925060808701356001600160401b038111156200480857600080fd5b6200481689828a0162004279565b979a9699509497509295939492505050565b6000806000606084860312156200483e57600080fd5b83356200484b8162004146565b95602085013595506040909401359392505050565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600082516200490381846020870162004375565b9190910192915050565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b8183823760009101908152919050565b634e487b7160e01b600052602160045260246000fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600060208284031215620049fc57600080fd5b81518015158114620012ea57600080fd5b6020808252601a908201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604082015260600190565b60208082526033908201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604082015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b8381526001600160a01b038316602082015260606040820181905260009062004afb908301846200439b565b95945050505050565b81835260006001600160fb1b0383111562004b1e57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0387811682528616602082015260a06040820181905260009062004b66908301868862004b04565b828103606084015262004b7b81858762004b04565b8381036080909401939093525050600081526020019695505050505050565b6001600160a01b038616815260606020820181905260009062004bc1908301868862004b04565b828103604084015262004bd681858762004b04565b98975050505050505050565b60008262004c0057634e487b7160e01b600052601260045260246000fd5b500690565b6000808585111562004c1657600080fd5b8386111562004c2457600080fd5b5050820193919092039150565b8035600f811062004c4157600080fd5b919050565b60006020828403121562004c5957600080fd5b620012ea8262004c31565b600081518084526020808501945080840160005b8381101562004c965781518752958201959082019060010162004c78565b509495945050505050565b60408152600062004cb6604083018562004c64565b828103602084015262004afb818562004c64565b6001600160a01b0385811682528416602082015260a06040820181905260009062004cf89083018562004c64565b828103606084015262004d0c818562004c64565b838103608090940193909352505060008152602001949350505050565b6001600160a01b038416815260806020820181905260009062004d4f9083018562004c64565b828103604084015262004d63818562004c64565b8381036060909401939093525050600081526020019392505050565b8051600f811062004da057634e487b7160e01b600052602160045260246000fd5b90915250565b62004db382825162004d7f565b6020818101516001600160a01b03908116918401919091526040808301519091169083015260608082015190830152608090810151910152565b60a08101620006fc828462004da6565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115620006fc57620006fc62004e13565b60006001820162004e545762004e5462004e13565b5060010190565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162004e9581601785016020880162004375565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162004ec881602884016020880162004375565b01602801949350505050565b62004ee182825162004d7f565b6000602082015160018060a01b0380821660208601528060408501511660408601525050606082015160a0606085015262004f2060a085018262004c64565b90506080830151848203608086015262004afb828262004c64565b602081526000620012ea602083018462004ed4565b60408152600062004f6660408301868862004b04565b828103602084015262004f7b81858762004b04565b979650505050505050565b60006020828403121562004f9957600080fd5b62004fa362004018565b905062004fb08262004c31565b815292915050565b600060a0828403121562004fcb57600080fd5b62004fd562004043565b905062004fe3838362004f86565b8152602082013562004ff58162004146565b602082015260408201356200500a8162004146565b80604083015250606082013560608201526080820135608082015292915050565b600060a082840312156200503e57600080fd5b620012ea838362004fb8565b6000602082840312156200505d57600080fd5b6200506762004018565b905081356001600160401b038111156200508057600080fd5b6200508e84828501620040ea565b82525092915050565b600060208284031215620050aa57600080fd5b81356001600160401b0380821115620050c257600080fd5b9083019060c08286031215620050d757600080fd5b620050e162004068565b620050ed868462004fb8565b815260a0830135828111156200510257600080fd5b62005110878286016200504a565b60208301525095945050505050565b81810381811115620006fc57620006fc62004e13565b600082601f8301126200514757600080fd5b813560206001600160401b0382111562005165576200516562004002565b8160051b620051768282016200408d565b92835284810182019282810190878511156200519157600080fd5b83870192505b8483101562004f7b5782358252918301919083019062005197565b600060a08284031215620051c557600080fd5b620051cf62004043565b9050620051dd838362004f86565b81526020820135620051ef8162004146565b60208201526040820135620052048162004146565b604082015260608201356001600160401b03808211156200522457600080fd5b620052328583860162005135565b606084015260808401359150808211156200524c57600080fd5b506200525b8482850162005135565b60808301525092915050565b6000602082840312156200527a57600080fd5b81356001600160401b038111156200529157600080fd5b6200529f84828501620051b2565b949350505050565b600060208284031215620052ba57600080fd5b81356001600160401b0380821115620052d257600080fd5b9083019060408286031215620052e757600080fd5b620052f162004068565b8235828111156200530157600080fd5b6200530f87828601620051b2565b8252506020830135828111156200510257600080fd5b6000602082840312156200533857600080fd5b81516001600160401b038111156200534f57600080fd5b8201601f810184136200536157600080fd5b8051620053726200410d82620040c0565b8181528560208385010111156200538857600080fd5b62004afb82602083016020860162004375565b60208152620053af60208201835162004da6565b6000602083015160c08084015280519050602060e08401526200529f6101008401826200439b565b6000816000190483118215151615620053f457620053f462004e13565b500290565b6000816200540b576200540b62004e13565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60208152600082516040602084015262005447606084018262004ed4565b602085810151858303601f190160408701525181835291925062004afb908301826200439b56fe60806040523480156200001157600080fd5b5060405162002ecd38038062002ecd8339810160408190526200003491620004ed565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d760201b620009121760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e660201b620009211760201c565b6200013d826200024460201b6200094a1760201c565b62000152620001e660201b620009211760201c565b6200016d60008051602062002ead83398151915280620002ae565b6200018860008051602062002ead83398151915233620002f9565b8015620001cf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50506200071c565b6001600160a01b03163b151590565b600054610100900460ff16620002425760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a05760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab8162000309565b50565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b62000305828262000370565b5050565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab81620003b3565b620003878282620003c160201b6200097d1760201c565b6000828152609760209081526040909120620003ae91839062000a0362000465821b17901c565b505050565b60cb62000305828262000650565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620003055760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004213390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200047c836001600160a01b03841662000485565b90505b92915050565b6000818152600183016020526040812054620004ce575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200047f565b5060006200047f565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156200050157600080fd5b82516001600160401b03808211156200051957600080fd5b818501915085601f8301126200052e57600080fd5b815181811115620005435762000543620004d7565b604051601f8201601f19908116603f011681019083821181831017156200056e576200056e620004d7565b8160405282815288868487010111156200058757600080fd5b600093505b82841015620005ab57848401860151818501870152928501926200058c565b600086848301015280965050505050505092915050565b600181811c90821680620005d757607f821691505b602082108103620005f857634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003ae57600081815260208120601f850160051c81016020861015620006275750805b601f850160051c820191505b81811015620006485782815560010162000633565b505050505050565b81516001600160401b038111156200066c576200066c620004d7565b62000684816200067d8454620005c2565b84620005fe565b602080601f831160018114620006bc5760008415620006a35750858301515b600019600386901b1c1916600185901b17855562000648565b600085815260208120601f198616915b82811015620006ed57888601518255948401946001909101908401620006cc565b50858210156200070c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612761806200072c6000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c873146102b4578063d5391393146102c7578063d547741f146102ee578063e985e9c514610301578063f242432a1461033d578063f5298aca1461035057600080fd5b8063731133e9146102485780639010d07c1461025b57806391d1485414610286578063a217fddf14610299578063a22cb465146102a157600080fd5b80632eb2c2d6116100ff5780632eb2c2d6146101dc5780632f2ff15d146101ef57806336568abe146102025780634e1273f4146102155780636b20c4541461023557600080fd5b8062fdd58e1461013b57806301ffc9a7146101615780630e89341c146101845780631f7fdffa146101a4578063248a9ca3146101b9575b600080fd5b61014e610149366004611a1f565b610363565b6040519081526020015b60405180910390f35b61017461016f366004611a5f565b6103fe565b6040519015158152602001610158565b610197610192366004611a7c565b610409565b6040516101589190611ae5565b6101b76101b2366004611c41565b61049d565b005b61014e6101c7366004611a7c565b60009081526065602052604090206001015490565b6101b76101ea366004611cd9565b61051e565b6101b76101fd366004611d82565b61056a565b6101b7610210366004611d82565b610594565b610228610223366004611dae565b610612565b6040516101589190611eb3565b6101b7610243366004611ec6565b61073b565b6101b7610256366004611f39565b61077e565b61026e610269366004611f8d565b6107f9565b6040516001600160a01b039091168152602001610158565b610174610294366004611d82565b610818565b61014e600081565b6101b76102af366004611faf565b610843565b61014e6102c2366004611a7c565b61084e565b61014e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101b76102fc366004611d82565b610865565b61017461030f366004611feb565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205460ff1690565b6101b761034b366004612015565b61088a565b6101b761035e366004612079565b6108cf565b60006001600160a01b0383166103d35760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b50600081815260c9602090815260408083206001600160a01b03861684529091529020545b92915050565b60006103f882610a18565b606060cb8054610418906120ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610444906120ac565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b50505050509050919050565b6104c77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b61050c5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610a58565b50505050565b6001600160a01b03851633148061053a575061053a853361030f565b6105565760405162461bcd60e51b81526004016103ca906120e6565b6105638585858585610ba4565b5050505050565b60008281526065602052604090206001015461058581610d43565b61058f8383610d4d565b505050565b6001600160a01b03811633146106045760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016103ca565b61060e8282610d6f565b5050565b606081518351146106775760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016103ca565b600083516001600160401b0381111561069257610692611af8565b6040519080825280602002602001820160405280156106bb578160200160208202803683370190505b50905060005b8451811015610733576107068582815181106106df576106df612135565b60200260200101518583815181106106f9576106f9612135565b6020026020010151610363565b82828151811061071857610718612135565b602090810291909101015261072c81612161565b90506106c1565b509392505050565b6001600160a01b0383163314806107575750610757833361030f565b6107735760405162461bcd60e51b81526004016103ca906120e6565b61058f838383610d91565b6107a87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b6107ed5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610f1e565b60008281526097602052604081206108119083610ffa565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61060e338383611006565b60008181526097602052604081206103f8906110e6565b60008281526065602052604090206001015461088081610d43565b61058f8383610d6f565b6001600160a01b0385163314806108a657506108a6853361030f565b6108c25760405162461bcd60e51b81526004016103ca906120e6565b61056385858585856110f0565b6001600160a01b0383163314806108eb57506108eb833361030f565b6109075760405162461bcd60e51b81526004016103ca906120e6565b61058f83838361121e565b6001600160a01b03163b151590565b600054610100900460ff166109485760405162461bcd60e51b81526004016103ca9061217a565b565b600054610100900460ff166109715760405162461bcd60e51b81526004016103ca9061217a565b61097a81611325565b50565b6109878282610818565b61060e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556109bf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610811836001600160a01b038416611355565b60006001600160e01b03198216636cdb3d1360e11b1480610a4957506001600160e01b031982166303a24d0760e21b145b806103f857506103f8826113a4565b6001600160a01b038416610a7e5760405162461bcd60e51b81526004016103ca906121c5565b8151835114610a9f5760405162461bcd60e51b81526004016103ca90612206565b3360005b8451811015610b3c57838181518110610abe57610abe612135565b602002602001015160c96000878481518110610adc57610adc612135565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254610b24919061224e565b90915550819050610b3481612161565b915050610aa3565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610b8d929190612261565b60405180910390a4610563816000878787876113c9565b8151835114610bc55760405162461bcd60e51b81526004016103ca90612206565b6001600160a01b038416610beb5760405162461bcd60e51b81526004016103ca9061228f565b3360005b8451811015610cd5576000858281518110610c0c57610c0c612135565b602002602001015190506000858381518110610c2a57610c2a612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038e168352909352919091205490915081811015610c7b5760405162461bcd60e51b81526004016103ca906122d4565b600083815260c9602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290610cba90849061224e565b9250508190555050505080610cce90612161565b9050610bef565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d25929190612261565b60405180910390a4610d3b8187878787876113c9565b505050505050565b61097a8133611524565b610d57828261097d565b600082815260976020526040902061058f9082610a03565b610d798282611588565b600082815260976020526040902061058f90826115ef565b6001600160a01b038316610db75760405162461bcd60e51b81526004016103ca9061231e565b8051825114610dd85760405162461bcd60e51b81526004016103ca90612206565b604080516020810190915260009081905233905b8351811015610eb1576000848281518110610e0957610e09612135565b602002602001015190506000848381518110610e2757610e27612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038c168352909352919091205490915081811015610e785760405162461bcd60e51b81526004016103ca90612361565b600092835260c9602090815260408085206001600160a01b038b1686529091529092209103905580610ea981612161565b915050610dec565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610f02929190612261565b60405180910390a4604080516020810190915260009052610518565b6001600160a01b038416610f445760405162461bcd60e51b81526004016103ca906121c5565b336000610f5085611604565b90506000610f5d85611604565b9050600086815260c9602090815260408083206001600160a01b038b16845290915281208054879290610f9190849061224e565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610ff18360008989898961164f565b50505050505050565b6000610811838361170a565b816001600160a01b0316836001600160a01b0316036110795760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016103ca565b6001600160a01b03838116600081815260ca6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006103f8825490565b6001600160a01b0384166111165760405162461bcd60e51b81526004016103ca9061228f565b33600061112285611604565b9050600061112f85611604565b9050600086815260c9602090815260408083206001600160a01b038c168452909152902054858110156111745760405162461bcd60e51b81526004016103ca906122d4565b600087815260c9602090815260408083206001600160a01b038d8116855292528083208985039055908a168252812080548892906111b390849061224e565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611213848a8a8a8a8a61164f565b505050505050505050565b6001600160a01b0383166112445760405162461bcd60e51b81526004016103ca9061231e565b33600061125084611604565b9050600061125d84611604565b604080516020808201835260009182905288825260c981528282206001600160a01b038b16835290522054909150848110156112ab5760405162461bcd60e51b81526004016103ca90612361565b600086815260c9602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4604080516020810190915260009052610ff1565b600054610100900460ff1661134c5760405162461bcd60e51b81526004016103ca9061217a565b61097a81611734565b600081815260018301602052604081205461139c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103f8565b5060006103f8565b60006001600160e01b03198216635a05180f60e01b14806103f857506103f882611740565b6001600160a01b0384163b15610d3b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061140d90899089908890889088906004016123a5565b6020604051808303816000875af1925050508015611448575060408051601f3d908101601f1916820190925261144591810190612403565b60015b6114f457611454612420565b806308c379a00361148d575061146861243c565b80611473575061148f565b8060405162461bcd60e51b81526004016103ca9190611ae5565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016103ca565b6001600160e01b0319811663bc197c8160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b61152e8282610818565b61060e57611546816001600160a01b03166014611775565b611551836020611775565b60405160200161156292919061250d565b60408051601f198184030181529082905262461bcd60e51b82526103ca91600401611ae5565b6115928282610818565b1561060e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610811836001600160a01b038416611910565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061163e5761163e612135565b602090810291909101015292915050565b6001600160a01b0384163b15610d3b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906116939089908990889088908890600401612582565b6020604051808303816000875af19250505080156116ce575060408051601f3d908101601f191682019092526116cb91810190612403565b60015b6116da57611454612420565b6001600160e01b0319811663f23a6e6160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b600082600001828154811061172157611721612135565b9060005260206000200154905092915050565b60cb61060e828261260d565b60006001600160e01b03198216637965db0b60e01b14806103f857506301ffc9a760e01b6001600160e01b03198316146103f8565b606060006117848360026126cc565b61178f90600261224e565b6001600160401b038111156117a6576117a6611af8565b6040519080825280601f01601f1916602001820160405280156117d0576020820181803683370190505b509050600360fc1b816000815181106117eb576117eb612135565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061181a5761181a612135565b60200101906001600160f81b031916908160001a905350600061183e8460026126cc565b61184990600161224e565b90505b60018111156118c1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061187d5761187d612135565b1a60f81b82828151811061189357611893612135565b60200101906001600160f81b031916908160001a90535060049490941c936118ba816126eb565b905061184c565b5083156108115760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016103ca565b600081815260018301602052604081205480156119f9576000611934600183612702565b855490915060009061194890600190612702565b90508181146119ad57600086600001828154811061196857611968612135565b906000526020600020015490508087600001848154811061198b5761198b612135565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119be576119be612715565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103f8565b60009150506103f8565b80356001600160a01b0381168114611a1a57600080fd5b919050565b60008060408385031215611a3257600080fd5b611a3b83611a03565b946020939093013593505050565b6001600160e01b03198116811461097a57600080fd5b600060208284031215611a7157600080fd5b813561081181611a49565b600060208284031215611a8e57600080fd5b5035919050565b60005b83811015611ab0578181015183820152602001611a98565b50506000910152565b60008151808452611ad1816020860160208601611a95565b601f01601f19169290920160200192915050565b6020815260006108116020830184611ab9565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715611b3357611b33611af8565b6040525050565b60006001600160401b03821115611b5357611b53611af8565b5060051b60200190565b600082601f830112611b6e57600080fd5b81356020611b7b82611b3a565b604051611b888282611b0e565b83815260059390931b8501820192828101915086841115611ba857600080fd5b8286015b84811015611bc35780358352918301918301611bac565b509695505050505050565b600082601f830112611bdf57600080fd5b81356001600160401b03811115611bf857611bf8611af8565b604051611c0f601f8301601f191660200182611b0e565b818152846020838601011115611c2457600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611c5757600080fd5b611c6085611a03565b935060208501356001600160401b0380821115611c7c57600080fd5b611c8888838901611b5d565b94506040870135915080821115611c9e57600080fd5b611caa88838901611b5d565b93506060870135915080821115611cc057600080fd5b50611ccd87828801611bce565b91505092959194509250565b600080600080600060a08688031215611cf157600080fd5b611cfa86611a03565b9450611d0860208701611a03565b935060408601356001600160401b0380821115611d2457600080fd5b611d3089838a01611b5d565b94506060880135915080821115611d4657600080fd5b611d5289838a01611b5d565b93506080880135915080821115611d6857600080fd5b50611d7588828901611bce565b9150509295509295909350565b60008060408385031215611d9557600080fd5b82359150611da560208401611a03565b90509250929050565b60008060408385031215611dc157600080fd5b82356001600160401b0380821115611dd857600080fd5b818501915085601f830112611dec57600080fd5b81356020611df982611b3a565b604051611e068282611b0e565b83815260059390931b8501820192828101915089841115611e2657600080fd5b948201945b83861015611e4b57611e3c86611a03565b82529482019490820190611e2b565b96505086013592505080821115611e6157600080fd5b50611e6e85828601611b5d565b9150509250929050565b600081518084526020808501945080840160005b83811015611ea857815187529582019590820190600101611e8c565b509495945050505050565b6020815260006108116020830184611e78565b600080600060608486031215611edb57600080fd5b611ee484611a03565b925060208401356001600160401b0380821115611f0057600080fd5b611f0c87838801611b5d565b93506040860135915080821115611f2257600080fd5b50611f2f86828701611b5d565b9150509250925092565b60008060008060808587031215611f4f57600080fd5b611f5885611a03565b9350602085013592506040850135915060608501356001600160401b03811115611f8157600080fd5b611ccd87828801611bce565b60008060408385031215611fa057600080fd5b50508035926020909101359150565b60008060408385031215611fc257600080fd5b611fcb83611a03565b915060208301358015158114611fe057600080fd5b809150509250929050565b60008060408385031215611ffe57600080fd5b61200783611a03565b9150611da560208401611a03565b600080600080600060a0868803121561202d57600080fd5b61203686611a03565b945061204460208701611a03565b9350604086013592506060860135915060808601356001600160401b0381111561206d57600080fd5b611d7588828901611bce565b60008060006060848603121561208e57600080fd5b61209784611a03565b95602085013595506040909401359392505050565b600181811c908216806120c057607f821691505b6020821081036120e057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602f908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526e195c881b9bdc88185c1c1c9bdd9959608a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016121735761217361214b565b5060010190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b808201808211156103f8576103f861214b565b6040815260006122746040830185611e78565b82810360208401526122868185611e78565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526023908201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526024908201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604082015263616e636560e01b606082015260800190565b6001600160a01b0386811682528516602082015260a0604082018190526000906123d190830186611e78565b82810360608401526123e38186611e78565b905082810360808401526123f78185611ab9565b98975050505050505050565b60006020828403121561241557600080fd5b815161081181611a49565b600060033d11156124395760046000803e5060005160e01c5b90565b600060443d101561244a5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561247957505050505090565b82850191508151818111156124915750505050505090565b843d87010160208285010111156124ab5750505050505090565b6124ba60208286010187611b0e565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612545816017850160208801611a95565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612576816028840160208801611a95565b01602801949350505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906125bc90830184611ab9565b979650505050505050565b601f82111561058f57600081815260208120601f850160051c810160208610156125ee5750805b601f850160051c820191505b81811015610d3b578281556001016125fa565b81516001600160401b0381111561262657612626611af8565b61263a8161263484546120ac565b846125c7565b602080601f83116001811461266f57600084156126575750858301515b600019600386901b1c1916600185901b178555610d3b565b600085815260208120601f198616915b8281101561269e5788860151825594840194600190910190840161267f565b50858210156126bc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008160001904831182151516156126e6576126e661214b565b500290565b6000816126fa576126fa61214b565b506000190190565b818103818111156103f8576103f861214b565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d84f746f173a737e6816e4123648488df6b8e119ec4b4fc93237fc9c098d976b64736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220cfd36f26d92e9c9eae1566679e3ea81f70e53e42b6fbaac0130e6c239bbfa4b264736f6c63430008100033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002795760003560e01c80636d6c68e61162000155578063c5d7666411620000c7578063dec2deb61162000086578063dec2deb6146200064e578063e3e50fa41462000663578063edcc12b5146200068f578063f23a6e6114620006a6578063f5b52e1f14620006bd57600080fd5b8063c5d7666414620005ca578063ca15c87314620005e1578063cb703bff14620005f8578063cc5b715b146200060f578063d547741f146200063757600080fd5b8063a217fddf1162000114578063a217fddf1462000549578063aebaaca91462000552578063b9581c501462000578578063bc197c811462000582578063c0e312dc14620005b357600080fd5b80636d6c68e614620004d95780638369091714620004ed578063884cee5a14620005045780639010d07c146200051b57806391d14854146200053257600080fd5b80632f2ff15d11620001ef57806350f4428011620001ae57806350f44280146200044d5780635573b8b6146200048357806357157cd914620004975780636ce681d214620004ae5780636d61128614620004c557600080fd5b80632f2ff15d14620003e757806336568abe14620003fe57806339927cf914620004155780633b690b6b146200042c5780633fa194ce146200043657600080fd5b806315ecfe5e116200023c57806315ecfe5e1462000355578063248a9ca3146200038c57806328c5e18214620003b25780632d32926214620003bc5780632dc151de14620003d357600080fd5b806301ffc9a7146200027e578063029996b814620002aa5780630b885ac314620002b65780630f1a8f7414620002cd5780631420de3f1462000312575b600080fd5b620002956200028f36600462003fd6565b620006d4565b60405190151581526020015b60405180910390f35b620002b462000702565b005b620002b4620002c73660046200415c565b6200075a565b620002f9620002de366004620041f1565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001620002a1565b62000346620003233660046200420b565b60d260209081526000938452604080852082529284528284209052825290205481565b604051908152602001620002a1565b620002f96200036636600462004246565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b620003466200039d366004620041f1565b60009081526065602052604090206001015490565b6200034662000839565b620002b4620003cd366004620042c4565b62000884565b60ca54620002f9906001600160a01b031681565b620002b4620003f836600462004246565b62000aa0565b620002b46200040f36600462004246565b62000ace565b620002956200042636600462004330565b62000b50565b6200034660cc5481565b620003466000805160206200833c83398151915281565b620004746040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002a19190620043c9565b60c954620002f9906001600160a01b031681565b620002b4620004a836600462004425565b62000bad565b620002b4620004bf3660046200415c565b62000dcd565b60cd54620002f9906001600160a01b031681565b60cb54620002f9906001600160a01b031681565b620002b4620004fe366004620044df565b62000ff0565b620002b4620005153660046200456a565b6200110e565b620002f96200052c366004620045cb565b620012d0565b620002956200054336600462004246565b620012f1565b62000346600081565b6200029562000563366004620045ee565b60d06020526000908152604090205460ff1681565b620002b46200131c565b62000599620005933660046200460e565b62001365565b6040516001600160e01b03199091168152602001620002a1565b620002b4620005c436600462004330565b620013ef565b620002b4620005db366004620046da565b6200150d565b62000346620005f2366004620041f1565b62001826565b620002b46200060936600462004749565b6200183f565b620003467ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b620002b46200064836600462004246565b62001997565b60cd546200029590600160a01b900460ff1681565b620002f962000674366004620045ee565b60cf602052600090815260409020546001600160a01b031681565b620002b4620006a0366004620045ee565b620019c0565b62000599620006b7366004620047a5565b62001adc565b620002b4620006ce36600462004828565b62001b64565b60006001600160e01b0319821663112fc36360e01b1480620006fc5750620006fc8262001c79565b92915050565b6200071d6000805160206200833c83398151915233620012f1565b620007455760405162461bcd60e51b81526004016200073c9062004860565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b600054610100900460ff16158080156200077b5750600054600160ff909116105b80620007975750303b15801562000797575060005460ff166001145b620007b65760405162461bcd60e51b81526004016200073c90620048a1565b6000805460ff191660011790558015620007da576000805461ff0019166101001790555b620007e9868686868662000dcd565b801562000831576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200086b9190620048ef565b6040516020818303038152906040528051906020012081565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051339450909250620008d091508490602001620048ef565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000912929101620048ef565b604051602081830303815290604052805190602001208103620009495760405162461bcd60e51b81526004016200073c906200490d565b6001600160a01b038216620009a15760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374207265636569766572206164647265737300000000000060448201526064016200073c565b600081815260ce60205260409020546001600160a01b0316620009d85760405162461bcd60e51b81526004016200073c906200495d565b60008888604051602001620009ef92919062004994565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000a5357600080fd5b505af115801562000a68573d6000803e3d6000fd5b505050600082815260ce602052604090205462000a95915082906001600160a01b031689338a8a62001ca1565b505050505050505050565b60008281526065602052604090206001015462000abd8162002020565b62000ac983836200202f565b505050565b6001600160a01b038116331462000b405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016200073c565b62000b4c828262002055565b5050565b6000806001600160a01b031660ce6000858560405160200162000b7592919062004994565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060405133945090925062000bf991508490602001620048ef565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000c3b929101620048ef565b60405160208183030381529060405280519060200120810362000c725760405162461bcd60e51b81526004016200073c906200490d565b6001600160a01b03821662000cca5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374207265636569766572206164647265737300000000000060448201526064016200073c565b600081815260ce60205260409020546001600160a01b031662000d015760405162461bcd60e51b81526004016200073c906200495d565b60008a8a60405160200162000d1892919062004994565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000d7c57600080fd5b505af115801562000d91573d6000803e3d6000fd5b505050600082815260ce602052604090205462000dc0915082906001600160a01b03168b338c8c8c8c6200207b565b5050505050505050505050565b600054610100900460ff161580801562000dee5750600054600160ff909116105b8062000e0a5750303b15801562000e0a575060005460ff166001145b62000e295760405162461bcd60e51b81526004016200073c90620048a1565b6000805460ff19166001179055801562000e4d576000805461ff0019166101001790555b6001600160a01b03821662000ea55760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f2062652073657460448201526064016200073c565b62000eaf620024b5565b62000ebc60003362002524565b62000ed76000805160206200833c8339815191523362002524565b62000f037ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362002524565b8560405160200162000f169190620048ef565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562000831576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200162000828565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929262001035929101620048ef565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b1580156200108857600080fd5b505af11580156200109d573d6000803e3d6000fd5b50505050620011076040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620010d79190620048ef565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168733888888886200207b565b5050505050565b60c9546001600160a01b031633146200116a5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f78790000000060448201526064016200073c565b838360cc54821415801562001186575062001186828262002530565b620011d45760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f7272656374000000000060448201526064016200073c565b6000620011e28585620025bb565b90506000600982600e811115620011fd57620011fd620049a4565b14806200121e5750600a82600e8111156200121c576200121c620049a4565b145b1562001239576200123188878762002612565b9050620012c6565b600b82600e811115620012505762001250620049a4565b1480620012715750600c82600e8111156200126f576200126f620049a4565b145b1562001284576200123188878762002abc565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b60448201526064016200073c565b5050505050505050565b6000828152609760205260408120620012ea908362002f01565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b620013376000805160206200833c83398151915233620012f1565b620013565760405162461bcd60e51b81526004016200073c9062004860565b60cd805460ff60a01b19169055565b60006001600160a01b0389163014620013c15760405162461bcd60e51b815260206004820152601d60248201527f5265766572742045524331313535206261746368207472616e7366657200000060448201526064016200073c565b507fbc197c819b3e337a6f9652dd10becd7eef83032af3b9d958d3d42f669414662198975050505050505050565b60ca546001600160a01b031633148062001411575062001411600033620012f1565b620014575760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b60448201526064016200073c565b600082826040516020016200146e92919062004994565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316620014ed5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f7420736574000000000000000060448201526064016200073c565b600090815260ce6020526040902080546001600160a01b03191690555050565b620015397ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012f1565b620015875760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c4520697320726571756972656460448201526064016200073c565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa90620015bb9087908790600401620049ba565b602060405180830381865afa158015620015d9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015ff9190620049e9565b620016465760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b60448201526064016200073c565b6001600160a01b0381163b6200169f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e74726163740060448201526064016200073c565b60008484604051602001620016b692919062004994565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b0388811683529452919091205490925016156200173a5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b60448201526064016200073c565b6001600160a01b038216600090815260d0602052604090205460ff1615620017a55760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c726561647920616464656400000000000000000060448201526064016200073c565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917ff86f4b9b158b421a62f31d8b430c86afba56c6bb611fb82bc115dd030903d36a91a45050505050565b6000818152609760205260408120620006fc9062002f0f565b60ca546001600160a01b031633148062001861575062001861600033620012f1565b620018a75760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b60448201526064016200073c565b60008383604051602001620018be92919062004994565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316156200193e5760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c7265616479207365740000000060448201526064016200073c565b6001600160a01b038216620019675760405162461bcd60e51b81526004016200073c906200495d565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b600082815260656020526040902060010154620019b48162002020565b62000ac9838362002055565b620019cd600033620012f1565b62001a1b5760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c45206973207265717569726564000060448201526064016200073c565b6001600160a01b03811662001a735760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f2062652073657460448201526064016200073c565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038716301462001b385760405162461bcd60e51b815260206004820152601760248201527f5265766572742045524331313535207472616e7366657200000000000000000060448201526064016200073c565b507ff23a6e612e1ff4830e658fe43f4e3cb4a5f8170bd5d9e69fb5d7a7fa9e4fdf979695505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929262001ba9929101620048ef565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b15801562001bfc57600080fd5b505af115801562001c11573d6000803e3d6000fd5b5050505062000ac96040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001c4b9190620048ef565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168533868662001ca1565b60006001600160e01b03198216630271189760e51b1480620006fc5750620006fc8262002f1a565b600086815260d1602090815260408083206001600160a01b0380891685529252822054168062001d0f57506001600160a01b038516600090815260d06020526040902054859060ff161562001d0a5760405162461bcd60e51b81526004016200073c9062004a0d565b600191505b6001600160a01b0381163b62001d635760405162461bcd60e51b81526020600482015260186024820152772737903a37b5b2b71031b637b7329037b71039b1b430b4b760411b60448201526064016200073c565b60405163e985e9c560e01b81523360048201523060248201526001600160a01b0382169063e985e9c590604401602060405180830381865afa15801562001dae573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001dd49190620049e9565b62001e1e5760405162461bcd60e51b81526020600482015260196024820152782737ba1030b63637bbb2b21022a92198989a9a902a37b5b2b760391b60448201526064016200073c565b600062001e2e8787878762002f42565b9050821562001f41576040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001e699190620048ef565b60405160208183030381529060405280519060200120890362001ea05760405162461bcd60e51b81526004016200073c9062004a44565b62001eaf898333888862002fab565b905062001ed3898362001ec28862003073565b62001ecd8862003073565b620030bd565b604051637921219560e11b81526001600160a01b0383169063f242432a9062001f0790339030908a908a9060040162004a97565b600060405180830381600087803b15801562001f2257600080fd5b505af115801562001f37573d6000803e3d6000fd5b5050505062001fab565b604051637a94c56560e11b815233600482015260248101869052604481018590526001600160a01b0383169063f5298aca90606401600060405180830381600087803b15801562001f9157600080fd5b505af115801562001fa6573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001fe1908c908c90869060040162004acf565b600060405180830381600087803b15801562001ffc57600080fd5b505af115801562002011573d6000803e3d6000fd5b50505050505050505050505050565b6200202c8133620031c9565b50565b6200203b828262003238565b600082815260976020526040902062000ac99082620032c2565b620020618282620032d9565b600082815260976020526040902062000ac9908262003343565b600088815260d1602090815260408083206001600160a01b03808b16855292528220541680620020e957506001600160a01b038716600090815260d06020526040902054879060ff1615620020e45760405162461bcd60e51b81526004016200073c9062004a0d565b600191505b6001600160a01b0381163b6200213d5760405162461bcd60e51b81526020600482015260186024820152772737903a37b5b2b71031b637b7329037b71039b1b430b4b760411b60448201526064016200073c565b60405163e985e9c560e01b81523360048201523060248201526001600160a01b0382169063e985e9c590604401602060405180830381865afa15801562002188573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620021ae9190620049e9565b620021f85760405162461bcd60e51b81526020600482015260196024820152782737ba1030b63637bbb2b21022a92198989a9a902a37b5b2b760391b60448201526064016200073c565b60006200226b898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b9182918501908490808284376000920191909152506200335a92505050565b90508215620023d3576040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620022a69190620048ef565b604051602081830303815290604052805190602001208b03620022dd5760405162461bcd60e51b81526004016200073c9062004a44565b620022ee8b83338a8a8a8a620033a9565b9050620023618b8389898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b918291850190849080828437600092019190915250620030bd92505050565b604051631759616b60e11b81526001600160a01b03831690632eb2c2d6906200239990339030908c908c908c908c9060040162004b37565b600060405180830381600087803b158015620023b457600080fd5b505af1158015620023c9573d6000803e3d6000fd5b505050506200243e565b604051631ac8311560e21b81526001600160a01b03831690636b20c45490620024099033908b908b908b908b9060040162004b9a565b600060405180830381600087803b1580156200242457600080fd5b505af115801562002439573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062002474908e908e90869060040162004acf565b600060405180830381600087803b1580156200248f57600080fd5b505af1158015620024a4573d6000803e3d6000fd5b505050505050505050505050505050565b600054610100900460ff16620025225760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200073c565b565b62000b4c82826200202f565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620025649190620048ef565b604051602081830303815290604052805190602001208314620025a457600083815260ce60205260409020546001600160a01b03838116911614620012ea565b5060cd546001600160a01b03908116911614919050565b600080620025cc83850185620041f1565b9050620025db60208262004be2565b6000036200260457620025fb620025f58483818862004c05565b620025bb565b915050620006fc565b620025fb8385018562004c46565b600080620026218484620025bb565b9050600080808080600986600e811115620026405762002640620049a4565b03620026c5576000620026548a8a6200352b565b90508060400151955080602001519450806060015193508060800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002882565b6000620026d38a8a620035e7565b9050806000015160400151955080600001516020015194508060000151606001519350806000015160800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b031603620028805760cd54600160a01b900460ff16620027c35760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c65640000000060448201526064016200073c565b602081015151604051620027d79062003f30565b620027e39190620043c9565b604051809103906000f08015801562002800573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918e917fae5aabebaedd1b95e68d95d1bc05734a63a8e451f94b37864515b78c532247d99190a45b505b600986600e811115620028995762002899620049a4565b148015620028ee57506040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620028d49190620048ef565b604051602081830303815290604052805190602001208a14155b801562002910575060008a815260d36020526040902062002910908562003689565b15620029d0576001600160a01b0384163b620029405760405162461bcd60e51b81526004016200073c9062004a0d565b620029628a85620029518662003073565b6200295c8662003073565b620036ac565b604051637921219560e11b81526001600160a01b0385169063f242432a906200299690309089908890889060040162004a97565b600060405180830381600087803b158015620029b157600080fd5b505af1158015620029c6573d6000803e3d6000fd5b5050505062002a4a565b60405163731133e960e01b81526001600160a01b0386811660048301526024820185905260448201849052608060648301526000608483015282169063731133e99060a401600060405180830381600087803b15801562002a3057600080fd5b505af115801562002a45573d6000803e3d6000fd5b505050505b806001600160a01b0316846001600160a01b03168b7f2349a6dafaf84dd371a44cd78bd587d9e750c3dfa1137d21f34f00e0d4babcb262002a8b8762003073565b62002a968762003073565b60405162002aa692919062004ca1565b60405180910390a4509298975050505050505050565b60008062002acb8484620025bb565b905060008060608082600b86600e81111562002aeb5762002aeb620049a4565b0362002b7057600062002aff8a8a620037b8565b90508060400151955080602001519450806060015193508060800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002d18565b600062002b7e8a8a62003879565b9050806000015160400151955080600001516020015194508060000151606001519350806000015160800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b03160362002d165760cd54600160a01b900460ff1662002c6e5760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c65640000000060448201526064016200073c565b60208101515160405162002c829062003f30565b62002c8e9190620043c9565b604051809103906000f08015801562002cab573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a81168086529190935281842080546001600160a01b03191693861693841790559051939550909290918e917fae5aabebaedd1b95e68d95d1bc05734a63a8e451f94b37864515b78c532247d99190a45b505b600b86600e81111562002d2f5762002d2f620049a4565b14801562002d8457506040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162002d6a9190620048ef565b604051602081830303815290604052805190602001208a14155b801562002da6575060008a815260d36020526040902062002da6908562003689565b1562002e52576001600160a01b0384163b62002dd65760405162461bcd60e51b81526004016200073c9062004a0d565b62002de48a858585620036ac565b604051631759616b60e11b81526001600160a01b03851690632eb2c2d69062002e1890309089908890889060040162004cca565b600060405180830381600087803b15801562002e3357600080fd5b505af115801562002e48573d6000803e3d6000fd5b5050505062002eb9565b604051630fbfeffd60e11b81526001600160a01b03821690631f7fdffa9062002e849088908790879060040162004d29565b600060405180830381600087803b15801562002e9f57600080fd5b505af115801562002eb4573d6000803e3d6000fd5b505050505b806001600160a01b0316846001600160a01b03168b7f2349a6dafaf84dd371a44cd78bd587d9e750c3dfa1137d21f34f00e0d4babcb2868660405162002aa692919062004ca1565b6000620012ea838362003920565b6000620006fc825490565b60006001600160e01b03198216635a05180f60e01b1480620006fc5750620006fc826200394d565b6040805160c081018252600960a0820190815281526001600160a01b0380871660208084019190915290861682840152606080830186905260808301859052925162002f919183910162004ded565b604051602081830303815290604052915050949350505050565b600085815260d3602052604081206060919062002fc9908762003689565b90508062002ffe5762002fdd878762003984565b62002ff68686868662002ff08b62003a9d565b62003b2e565b91506200300f565b6200300c8686868662002f42565b91505b856001600160a01b0316877f601046fc8dbb772c2b88d30850532ffec5253f2e73c855af1c5f318a7a4562b0620030468762003073565b620030518762003073565b6040516200306192919062004ca1565b60405180910390a35095945050505050565b604080516001808252818301909252606091602080830190803683370190505090508181600081518110620030ac57620030ac62004dfd565b602002602001018181525050919050565b8051825114620031105760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206c656e677468206f662061727261797300000000000060448201526064016200073c565b60005b8251811015620011075781818151811062003132576200313262004dfd565b602002602001015160d260008781526020019081526020016000206000866001600160a01b03166001600160a01b03168152602001908152602001600020600085848151811062003187576200318762004dfd565b602002602001015181526020019081526020016000206000828254620031ae919062004e29565b90915550819050620031c08162004e3f565b91505062003113565b620031d58282620012f1565b62000b4c57620031f0816001600160a01b0316601462003bb5565b620031fd83602062003bb5565b6040516020016200321092919062004e5b565b60408051601f198184030181529082905262461bcd60e51b82526200073c91600401620043c9565b620032448282620012f1565b62000b4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200327e3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012ea836001600160a01b03841662003d6e565b620032e58282620012f1565b1562000b4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012ea836001600160a01b03841662003dc0565b6040805160c081018252600b60a0820190815281526001600160a01b0380871660208084019190915290861682840152606080830186905260808301859052925162002f919183910162004f3b565b600087815260d36020526040812060609190620033c7908962003689565b9050806200346157620033db898962003984565b62003459888888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152506200345392508f915062003a9d9050565b62003ec4565b9150620034d5565b620034d2888888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152506200335a92505050565b91505b876001600160a01b0316897f601046fc8dbb772c2b88d30850532ffec5253f2e73c855af1c5f318a7a4562b08888888860405162003517949392919062004f50565b60405180910390a350979650505050505050565b6040805160c081018252600060a0820181815282526020820181905291810182905260608101829052608081019190915260096200356a8484620025bb565b600e8111156200357e576200357e620049a4565b14620035d95760405162461bcd60e51b8152602060048201526024808201527f4d6573736167652074797065206973206e6f742045524331313535207472616e60448201526339b332b960e11b60648201526084016200073c565b620012ea828401846200502b565b620035f162003f3e565b600a620035ff8484620025bb565b600e811115620036135762003613620049a4565b146200367b5760405162461bcd60e51b815260206004820152603060248201527f4d6573736167652074797065206973206e6f742045524331313535416e64546f60448201526f35b2b724b73337903a3930b739b332b960811b60648201526084016200073c565b620012ea8284018462005097565b6001600160a01b03811660009081526001830160205260408120541515620012ea565b8051825114620036ff5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206c656e677468206f662061727261797300000000000060448201526064016200073c565b60005b8251811015620011075781818151811062003721576200372162004dfd565b602002602001015160d260008781526020019081526020016000206000866001600160a01b03166001600160a01b03168152602001908152602001600020600085848151811062003776576200377662004dfd565b6020026020010151815260200190815260200160002060008282546200379d91906200511f565b90915550819050620037af8162004e3f565b91505062003702565b6040805160c081018252600060a082018181528252602082018190529181019190915260608082018190526080820152600b620037f68484620025bb565b600e8111156200380a576200380a620049a4565b146200386b5760405162461bcd60e51b815260206004820152602960248201527f4d6573736167652074797065206973206e6f7420455243313135354261746368604482015268103a3930b739b332b960b91b60648201526084016200073c565b620012ea8284018462005267565b6200388362003f97565b600c620038918484620025bb565b600e811115620038a557620038a5620049a4565b14620039125760405162461bcd60e51b815260206004820152603560248201527f4d6573736167652074797065206973206e6f742045524331313535426174636860448201527420b7322a37b5b2b724b73337903a3930b739b332b960591b60648201526084016200073c565b620012ea82840184620052a7565b60008260000182815481106200393a576200393a62004dfd565b9060005260206000200154905092915050565b60006001600160e01b03198216637965db0b60e01b1480620006fc57506301ffc9a760e01b6001600160e01b0319831614620006fc565b6001600160a01b0381163b620039dd5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e74726163740060448201526064016200073c565b600082815260d360205260409020620039f7908262003689565b1562003a465760405162461bcd60e51b815260206004820152601f60248201527f4552433131353520546f6b656e2077617320616c72656164792061646465640060448201526064016200073c565b600082815260d36020526040902062003a609082620032c2565b506040516000906001600160a01b0383169084907ff86f4b9b158b421a62f31d8b430c86afba56c6bb611fb82bc115dd030903d36a908490a45050565b6040805160208101909152606081526040805160208101918290526303a24d0760e21b90915260006024820152806001600160a01b038416630e89341c60448301600060405180830381865afa15801562003afc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262003b26919081019062005325565b905292915050565b604080516101008101825260609160009190819081018060e0830180600a81525081526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018781525081526020018481525090508060405160200162003b9a91906200539b565b60405160208183030381529060405291505095945050505050565b6060600062003bc6836002620053d7565b62003bd390600262004e29565b6001600160401b0381111562003bed5762003bed62004002565b6040519080825280601f01601f19166020018201604052801562003c18576020820181803683370190505b509050600360fc1b8160008151811062003c365762003c3662004dfd565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062003c685762003c6862004dfd565b60200101906001600160f81b031916908160001a905350600062003c8e846002620053d7565b62003c9b90600162004e29565b90505b600181111562003d1d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062003cd35762003cd362004dfd565b1a60f81b82828151811062003cec5762003cec62004dfd565b60200101906001600160f81b031916908160001a90535060049490941c9362003d1581620053f9565b905062003c9e565b508315620012ea5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016200073c565b600081815260018301602052604081205462003db757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620006fc565b506000620006fc565b6000818152600183016020526040812054801562003eb957600062003de76001836200511f565b855490915060009062003dfd906001906200511f565b905081811462003e6957600086600001828154811062003e215762003e2162004dfd565b906000526020600020015490508087600001848154811062003e475762003e4762004dfd565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003e7d5762003e7d62005413565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620006fc565b6000915050620006fc565b604080516101008101825260609160009190819081018060e0830180600c81525081526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018781525081526020018481525090508060405160200162003b9a919062005429565b612ecd806200546f83390190565b6040805161010081018252600060e08201818152928201928352606082018190526080820181905260a0820181905260c08201529081905b815260200162003f926040518060200160405280606081525090565b905290565b6040805161010081018252600060e082018181529282019283526060808301829052608083019190915260a0820181905260c082015290819062003f76565b60006020828403121562003fe957600080fd5b81356001600160e01b031981168114620012ea57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051602081016001600160401b03811182821017156200403d576200403d62004002565b60405290565b60405160a081016001600160401b03811182821017156200403d576200403d62004002565b604080519081016001600160401b03811182821017156200403d576200403d62004002565b604051601f8201601f191681016001600160401b0381118282101715620040b857620040b862004002565b604052919050565b60006001600160401b03821115620040dc57620040dc62004002565b50601f01601f191660200190565b600082601f830112620040fc57600080fd5b8135620041136200410d82620040c0565b6200408d565b8181528460208386010111156200412957600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b03811681146200202c57600080fd5b600080600080600060a086880312156200417557600080fd5b85356001600160401b038111156200418c57600080fd5b6200419a88828901620040ea565b9550506020860135620041ad8162004146565b93506040860135620041bf8162004146565b92506060860135620041d18162004146565b91506080860135620041e38162004146565b809150509295509295909350565b6000602082840312156200420457600080fd5b5035919050565b6000806000606084860312156200422157600080fd5b833592506020840135620042358162004146565b929592945050506040919091013590565b600080604083850312156200425a57600080fd5b8235915060208301356200426e8162004146565b809150509250929050565b60008083601f8401126200428c57600080fd5b5081356001600160401b03811115620042a457600080fd5b602083019150836020828501011115620042bd57600080fd5b9250929050565b600080600080600060808688031215620042dd57600080fd5b85356001600160401b03811115620042f457600080fd5b620043028882890162004279565b9096509450506020860135620043188162004146565b94979396509394604081013594506060013592915050565b600080602083850312156200434457600080fd5b82356001600160401b038111156200435b57600080fd5b620043698582860162004279565b90969095509350505050565b60005b838110156200439257818101518382015260200162004378565b50506000910152565b60008151808452620043b581602086016020860162004375565b601f01601f19169290920160200192915050565b602081526000620012ea60208301846200439b565b60008083601f840112620043f157600080fd5b5081356001600160401b038111156200440957600080fd5b6020830191508360208260051b8501011115620042bd57600080fd5b60008060008060008060006080888a0312156200444157600080fd5b87356001600160401b03808211156200445957600080fd5b620044678b838c0162004279565b909950975060208a013591506200447e8262004146565b909550604089013590808211156200449557600080fd5b620044a38b838c01620043de565b909650945060608a0135915080821115620044bd57600080fd5b50620044cc8a828b01620043de565b989b979a50959850939692959293505050565b600080600080600060608688031215620044f857600080fd5b8535620045058162004146565b945060208601356001600160401b03808211156200452257600080fd5b6200453089838a01620043de565b909650945060408801359150808211156200454a57600080fd5b506200455988828901620043de565b969995985093965092949392505050565b600080600080606085870312156200458157600080fd5b843593506020850135620045958162004146565b925060408501356001600160401b03811115620045b157600080fd5b620045bf8782880162004279565b95989497509550505050565b60008060408385031215620045df57600080fd5b50508035926020909101359150565b6000602082840312156200460157600080fd5b8135620012ea8162004146565b60008060008060008060008060a0898b0312156200462b57600080fd5b8835620046388162004146565b975060208901356200464a8162004146565b965060408901356001600160401b03808211156200466757600080fd5b620046758c838d01620043de565b909850965060608b01359150808211156200468f57600080fd5b6200469d8c838d01620043de565b909650945060808b0135915080821115620046b757600080fd5b50620046c68b828c0162004279565b999c989b5096995094979396929594505050565b60008060008060608587031215620046f157600080fd5b84356001600160401b038111156200470857600080fd5b620047168782880162004279565b90955093505060208501356200472c8162004146565b915060408501356200473e8162004146565b939692955090935050565b6000806000604084860312156200475f57600080fd5b83356001600160401b038111156200477657600080fd5b620047848682870162004279565b90945092505060208401356200479a8162004146565b809150509250925092565b60008060008060008060a08789031215620047bf57600080fd5b8635620047cc8162004146565b95506020870135620047de8162004146565b9450604087013593506060870135925060808701356001600160401b038111156200480857600080fd5b6200481689828a0162004279565b979a9699509497509295939492505050565b6000806000606084860312156200483e57600080fd5b83356200484b8162004146565b95602085013595506040909401359392505050565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600082516200490381846020870162004375565b9190910192915050565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b8183823760009101908152919050565b634e487b7160e01b600052602160045260246000fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600060208284031215620049fc57600080fd5b81518015158114620012ea57600080fd5b6020808252601a908201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604082015260600190565b60208082526033908201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604082015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b8381526001600160a01b038316602082015260606040820181905260009062004afb908301846200439b565b95945050505050565b81835260006001600160fb1b0383111562004b1e57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0387811682528616602082015260a06040820181905260009062004b66908301868862004b04565b828103606084015262004b7b81858762004b04565b8381036080909401939093525050600081526020019695505050505050565b6001600160a01b038616815260606020820181905260009062004bc1908301868862004b04565b828103604084015262004bd681858762004b04565b98975050505050505050565b60008262004c0057634e487b7160e01b600052601260045260246000fd5b500690565b6000808585111562004c1657600080fd5b8386111562004c2457600080fd5b5050820193919092039150565b8035600f811062004c4157600080fd5b919050565b60006020828403121562004c5957600080fd5b620012ea8262004c31565b600081518084526020808501945080840160005b8381101562004c965781518752958201959082019060010162004c78565b509495945050505050565b60408152600062004cb6604083018562004c64565b828103602084015262004afb818562004c64565b6001600160a01b0385811682528416602082015260a06040820181905260009062004cf89083018562004c64565b828103606084015262004d0c818562004c64565b838103608090940193909352505060008152602001949350505050565b6001600160a01b038416815260806020820181905260009062004d4f9083018562004c64565b828103604084015262004d63818562004c64565b8381036060909401939093525050600081526020019392505050565b8051600f811062004da057634e487b7160e01b600052602160045260246000fd5b90915250565b62004db382825162004d7f565b6020818101516001600160a01b03908116918401919091526040808301519091169083015260608082015190830152608090810151910152565b60a08101620006fc828462004da6565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115620006fc57620006fc62004e13565b60006001820162004e545762004e5462004e13565b5060010190565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162004e9581601785016020880162004375565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162004ec881602884016020880162004375565b01602801949350505050565b62004ee182825162004d7f565b6000602082015160018060a01b0380821660208601528060408501511660408601525050606082015160a0606085015262004f2060a085018262004c64565b90506080830151848203608086015262004afb828262004c64565b602081526000620012ea602083018462004ed4565b60408152600062004f6660408301868862004b04565b828103602084015262004f7b81858762004b04565b979650505050505050565b60006020828403121562004f9957600080fd5b62004fa362004018565b905062004fb08262004c31565b815292915050565b600060a0828403121562004fcb57600080fd5b62004fd562004043565b905062004fe3838362004f86565b8152602082013562004ff58162004146565b602082015260408201356200500a8162004146565b80604083015250606082013560608201526080820135608082015292915050565b600060a082840312156200503e57600080fd5b620012ea838362004fb8565b6000602082840312156200505d57600080fd5b6200506762004018565b905081356001600160401b038111156200508057600080fd5b6200508e84828501620040ea565b82525092915050565b600060208284031215620050aa57600080fd5b81356001600160401b0380821115620050c257600080fd5b9083019060c08286031215620050d757600080fd5b620050e162004068565b620050ed868462004fb8565b815260a0830135828111156200510257600080fd5b62005110878286016200504a565b60208301525095945050505050565b81810381811115620006fc57620006fc62004e13565b600082601f8301126200514757600080fd5b813560206001600160401b0382111562005165576200516562004002565b8160051b620051768282016200408d565b92835284810182019282810190878511156200519157600080fd5b83870192505b8483101562004f7b5782358252918301919083019062005197565b600060a08284031215620051c557600080fd5b620051cf62004043565b9050620051dd838362004f86565b81526020820135620051ef8162004146565b60208201526040820135620052048162004146565b604082015260608201356001600160401b03808211156200522457600080fd5b620052328583860162005135565b606084015260808401359150808211156200524c57600080fd5b506200525b8482850162005135565b60808301525092915050565b6000602082840312156200527a57600080fd5b81356001600160401b038111156200529157600080fd5b6200529f84828501620051b2565b949350505050565b600060208284031215620052ba57600080fd5b81356001600160401b0380821115620052d257600080fd5b9083019060408286031215620052e757600080fd5b620052f162004068565b8235828111156200530157600080fd5b6200530f87828601620051b2565b8252506020830135828111156200510257600080fd5b6000602082840312156200533857600080fd5b81516001600160401b038111156200534f57600080fd5b8201601f810184136200536157600080fd5b8051620053726200410d82620040c0565b8181528560208385010111156200538857600080fd5b62004afb82602083016020860162004375565b60208152620053af60208201835162004da6565b6000602083015160c08084015280519050602060e08401526200529f6101008401826200439b565b6000816000190483118215151615620053f457620053f462004e13565b500290565b6000816200540b576200540b62004e13565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60208152600082516040602084015262005447606084018262004ed4565b602085810151858303601f190160408701525181835291925062004afb908301826200439b56fe60806040523480156200001157600080fd5b5060405162002ecd38038062002ecd8339810160408190526200003491620004ed565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d760201b620009121760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e660201b620009211760201c565b6200013d826200024460201b6200094a1760201c565b62000152620001e660201b620009211760201c565b6200016d60008051602062002ead83398151915280620002ae565b6200018860008051602062002ead83398151915233620002f9565b8015620001cf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50506200071c565b6001600160a01b03163b151590565b600054610100900460ff16620002425760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a05760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab8162000309565b50565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b62000305828262000370565b5050565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab81620003b3565b620003878282620003c160201b6200097d1760201c565b6000828152609760209081526040909120620003ae91839062000a0362000465821b17901c565b505050565b60cb62000305828262000650565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620003055760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004213390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200047c836001600160a01b03841662000485565b90505b92915050565b6000818152600183016020526040812054620004ce575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200047f565b5060006200047f565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156200050157600080fd5b82516001600160401b03808211156200051957600080fd5b818501915085601f8301126200052e57600080fd5b815181811115620005435762000543620004d7565b604051601f8201601f19908116603f011681019083821181831017156200056e576200056e620004d7565b8160405282815288868487010111156200058757600080fd5b600093505b82841015620005ab57848401860151818501870152928501926200058c565b600086848301015280965050505050505092915050565b600181811c90821680620005d757607f821691505b602082108103620005f857634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003ae57600081815260208120601f850160051c81016020861015620006275750805b601f850160051c820191505b81811015620006485782815560010162000633565b505050505050565b81516001600160401b038111156200066c576200066c620004d7565b62000684816200067d8454620005c2565b84620005fe565b602080601f831160018114620006bc5760008415620006a35750858301515b600019600386901b1c1916600185901b17855562000648565b600085815260208120601f198616915b82811015620006ed57888601518255948401946001909101908401620006cc565b50858210156200070c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612761806200072c6000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c873146102b4578063d5391393146102c7578063d547741f146102ee578063e985e9c514610301578063f242432a1461033d578063f5298aca1461035057600080fd5b8063731133e9146102485780639010d07c1461025b57806391d1485414610286578063a217fddf14610299578063a22cb465146102a157600080fd5b80632eb2c2d6116100ff5780632eb2c2d6146101dc5780632f2ff15d146101ef57806336568abe146102025780634e1273f4146102155780636b20c4541461023557600080fd5b8062fdd58e1461013b57806301ffc9a7146101615780630e89341c146101845780631f7fdffa146101a4578063248a9ca3146101b9575b600080fd5b61014e610149366004611a1f565b610363565b6040519081526020015b60405180910390f35b61017461016f366004611a5f565b6103fe565b6040519015158152602001610158565b610197610192366004611a7c565b610409565b6040516101589190611ae5565b6101b76101b2366004611c41565b61049d565b005b61014e6101c7366004611a7c565b60009081526065602052604090206001015490565b6101b76101ea366004611cd9565b61051e565b6101b76101fd366004611d82565b61056a565b6101b7610210366004611d82565b610594565b610228610223366004611dae565b610612565b6040516101589190611eb3565b6101b7610243366004611ec6565b61073b565b6101b7610256366004611f39565b61077e565b61026e610269366004611f8d565b6107f9565b6040516001600160a01b039091168152602001610158565b610174610294366004611d82565b610818565b61014e600081565b6101b76102af366004611faf565b610843565b61014e6102c2366004611a7c565b61084e565b61014e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101b76102fc366004611d82565b610865565b61017461030f366004611feb565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205460ff1690565b6101b761034b366004612015565b61088a565b6101b761035e366004612079565b6108cf565b60006001600160a01b0383166103d35760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b50600081815260c9602090815260408083206001600160a01b03861684529091529020545b92915050565b60006103f882610a18565b606060cb8054610418906120ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610444906120ac565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b50505050509050919050565b6104c77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b61050c5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610a58565b50505050565b6001600160a01b03851633148061053a575061053a853361030f565b6105565760405162461bcd60e51b81526004016103ca906120e6565b6105638585858585610ba4565b5050505050565b60008281526065602052604090206001015461058581610d43565b61058f8383610d4d565b505050565b6001600160a01b03811633146106045760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016103ca565b61060e8282610d6f565b5050565b606081518351146106775760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016103ca565b600083516001600160401b0381111561069257610692611af8565b6040519080825280602002602001820160405280156106bb578160200160208202803683370190505b50905060005b8451811015610733576107068582815181106106df576106df612135565b60200260200101518583815181106106f9576106f9612135565b6020026020010151610363565b82828151811061071857610718612135565b602090810291909101015261072c81612161565b90506106c1565b509392505050565b6001600160a01b0383163314806107575750610757833361030f565b6107735760405162461bcd60e51b81526004016103ca906120e6565b61058f838383610d91565b6107a87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b6107ed5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610f1e565b60008281526097602052604081206108119083610ffa565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61060e338383611006565b60008181526097602052604081206103f8906110e6565b60008281526065602052604090206001015461088081610d43565b61058f8383610d6f565b6001600160a01b0385163314806108a657506108a6853361030f565b6108c25760405162461bcd60e51b81526004016103ca906120e6565b61056385858585856110f0565b6001600160a01b0383163314806108eb57506108eb833361030f565b6109075760405162461bcd60e51b81526004016103ca906120e6565b61058f83838361121e565b6001600160a01b03163b151590565b600054610100900460ff166109485760405162461bcd60e51b81526004016103ca9061217a565b565b600054610100900460ff166109715760405162461bcd60e51b81526004016103ca9061217a565b61097a81611325565b50565b6109878282610818565b61060e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556109bf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610811836001600160a01b038416611355565b60006001600160e01b03198216636cdb3d1360e11b1480610a4957506001600160e01b031982166303a24d0760e21b145b806103f857506103f8826113a4565b6001600160a01b038416610a7e5760405162461bcd60e51b81526004016103ca906121c5565b8151835114610a9f5760405162461bcd60e51b81526004016103ca90612206565b3360005b8451811015610b3c57838181518110610abe57610abe612135565b602002602001015160c96000878481518110610adc57610adc612135565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254610b24919061224e565b90915550819050610b3481612161565b915050610aa3565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610b8d929190612261565b60405180910390a4610563816000878787876113c9565b8151835114610bc55760405162461bcd60e51b81526004016103ca90612206565b6001600160a01b038416610beb5760405162461bcd60e51b81526004016103ca9061228f565b3360005b8451811015610cd5576000858281518110610c0c57610c0c612135565b602002602001015190506000858381518110610c2a57610c2a612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038e168352909352919091205490915081811015610c7b5760405162461bcd60e51b81526004016103ca906122d4565b600083815260c9602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290610cba90849061224e565b9250508190555050505080610cce90612161565b9050610bef565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d25929190612261565b60405180910390a4610d3b8187878787876113c9565b505050505050565b61097a8133611524565b610d57828261097d565b600082815260976020526040902061058f9082610a03565b610d798282611588565b600082815260976020526040902061058f90826115ef565b6001600160a01b038316610db75760405162461bcd60e51b81526004016103ca9061231e565b8051825114610dd85760405162461bcd60e51b81526004016103ca90612206565b604080516020810190915260009081905233905b8351811015610eb1576000848281518110610e0957610e09612135565b602002602001015190506000848381518110610e2757610e27612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038c168352909352919091205490915081811015610e785760405162461bcd60e51b81526004016103ca90612361565b600092835260c9602090815260408085206001600160a01b038b1686529091529092209103905580610ea981612161565b915050610dec565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610f02929190612261565b60405180910390a4604080516020810190915260009052610518565b6001600160a01b038416610f445760405162461bcd60e51b81526004016103ca906121c5565b336000610f5085611604565b90506000610f5d85611604565b9050600086815260c9602090815260408083206001600160a01b038b16845290915281208054879290610f9190849061224e565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610ff18360008989898961164f565b50505050505050565b6000610811838361170a565b816001600160a01b0316836001600160a01b0316036110795760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016103ca565b6001600160a01b03838116600081815260ca6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006103f8825490565b6001600160a01b0384166111165760405162461bcd60e51b81526004016103ca9061228f565b33600061112285611604565b9050600061112f85611604565b9050600086815260c9602090815260408083206001600160a01b038c168452909152902054858110156111745760405162461bcd60e51b81526004016103ca906122d4565b600087815260c9602090815260408083206001600160a01b038d8116855292528083208985039055908a168252812080548892906111b390849061224e565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611213848a8a8a8a8a61164f565b505050505050505050565b6001600160a01b0383166112445760405162461bcd60e51b81526004016103ca9061231e565b33600061125084611604565b9050600061125d84611604565b604080516020808201835260009182905288825260c981528282206001600160a01b038b16835290522054909150848110156112ab5760405162461bcd60e51b81526004016103ca90612361565b600086815260c9602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4604080516020810190915260009052610ff1565b600054610100900460ff1661134c5760405162461bcd60e51b81526004016103ca9061217a565b61097a81611734565b600081815260018301602052604081205461139c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103f8565b5060006103f8565b60006001600160e01b03198216635a05180f60e01b14806103f857506103f882611740565b6001600160a01b0384163b15610d3b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061140d90899089908890889088906004016123a5565b6020604051808303816000875af1925050508015611448575060408051601f3d908101601f1916820190925261144591810190612403565b60015b6114f457611454612420565b806308c379a00361148d575061146861243c565b80611473575061148f565b8060405162461bcd60e51b81526004016103ca9190611ae5565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016103ca565b6001600160e01b0319811663bc197c8160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b61152e8282610818565b61060e57611546816001600160a01b03166014611775565b611551836020611775565b60405160200161156292919061250d565b60408051601f198184030181529082905262461bcd60e51b82526103ca91600401611ae5565b6115928282610818565b1561060e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610811836001600160a01b038416611910565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061163e5761163e612135565b602090810291909101015292915050565b6001600160a01b0384163b15610d3b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906116939089908990889088908890600401612582565b6020604051808303816000875af19250505080156116ce575060408051601f3d908101601f191682019092526116cb91810190612403565b60015b6116da57611454612420565b6001600160e01b0319811663f23a6e6160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b600082600001828154811061172157611721612135565b9060005260206000200154905092915050565b60cb61060e828261260d565b60006001600160e01b03198216637965db0b60e01b14806103f857506301ffc9a760e01b6001600160e01b03198316146103f8565b606060006117848360026126cc565b61178f90600261224e565b6001600160401b038111156117a6576117a6611af8565b6040519080825280601f01601f1916602001820160405280156117d0576020820181803683370190505b509050600360fc1b816000815181106117eb576117eb612135565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061181a5761181a612135565b60200101906001600160f81b031916908160001a905350600061183e8460026126cc565b61184990600161224e565b90505b60018111156118c1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061187d5761187d612135565b1a60f81b82828151811061189357611893612135565b60200101906001600160f81b031916908160001a90535060049490941c936118ba816126eb565b905061184c565b5083156108115760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016103ca565b600081815260018301602052604081205480156119f9576000611934600183612702565b855490915060009061194890600190612702565b90508181146119ad57600086600001828154811061196857611968612135565b906000526020600020015490508087600001848154811061198b5761198b612135565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119be576119be612715565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103f8565b60009150506103f8565b80356001600160a01b0381168114611a1a57600080fd5b919050565b60008060408385031215611a3257600080fd5b611a3b83611a03565b946020939093013593505050565b6001600160e01b03198116811461097a57600080fd5b600060208284031215611a7157600080fd5b813561081181611a49565b600060208284031215611a8e57600080fd5b5035919050565b60005b83811015611ab0578181015183820152602001611a98565b50506000910152565b60008151808452611ad1816020860160208601611a95565b601f01601f19169290920160200192915050565b6020815260006108116020830184611ab9565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715611b3357611b33611af8565b6040525050565b60006001600160401b03821115611b5357611b53611af8565b5060051b60200190565b600082601f830112611b6e57600080fd5b81356020611b7b82611b3a565b604051611b888282611b0e565b83815260059390931b8501820192828101915086841115611ba857600080fd5b8286015b84811015611bc35780358352918301918301611bac565b509695505050505050565b600082601f830112611bdf57600080fd5b81356001600160401b03811115611bf857611bf8611af8565b604051611c0f601f8301601f191660200182611b0e565b818152846020838601011115611c2457600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611c5757600080fd5b611c6085611a03565b935060208501356001600160401b0380821115611c7c57600080fd5b611c8888838901611b5d565b94506040870135915080821115611c9e57600080fd5b611caa88838901611b5d565b93506060870135915080821115611cc057600080fd5b50611ccd87828801611bce565b91505092959194509250565b600080600080600060a08688031215611cf157600080fd5b611cfa86611a03565b9450611d0860208701611a03565b935060408601356001600160401b0380821115611d2457600080fd5b611d3089838a01611b5d565b94506060880135915080821115611d4657600080fd5b611d5289838a01611b5d565b93506080880135915080821115611d6857600080fd5b50611d7588828901611bce565b9150509295509295909350565b60008060408385031215611d9557600080fd5b82359150611da560208401611a03565b90509250929050565b60008060408385031215611dc157600080fd5b82356001600160401b0380821115611dd857600080fd5b818501915085601f830112611dec57600080fd5b81356020611df982611b3a565b604051611e068282611b0e565b83815260059390931b8501820192828101915089841115611e2657600080fd5b948201945b83861015611e4b57611e3c86611a03565b82529482019490820190611e2b565b96505086013592505080821115611e6157600080fd5b50611e6e85828601611b5d565b9150509250929050565b600081518084526020808501945080840160005b83811015611ea857815187529582019590820190600101611e8c565b509495945050505050565b6020815260006108116020830184611e78565b600080600060608486031215611edb57600080fd5b611ee484611a03565b925060208401356001600160401b0380821115611f0057600080fd5b611f0c87838801611b5d565b93506040860135915080821115611f2257600080fd5b50611f2f86828701611b5d565b9150509250925092565b60008060008060808587031215611f4f57600080fd5b611f5885611a03565b9350602085013592506040850135915060608501356001600160401b03811115611f8157600080fd5b611ccd87828801611bce565b60008060408385031215611fa057600080fd5b50508035926020909101359150565b60008060408385031215611fc257600080fd5b611fcb83611a03565b915060208301358015158114611fe057600080fd5b809150509250929050565b60008060408385031215611ffe57600080fd5b61200783611a03565b9150611da560208401611a03565b600080600080600060a0868803121561202d57600080fd5b61203686611a03565b945061204460208701611a03565b9350604086013592506060860135915060808601356001600160401b0381111561206d57600080fd5b611d7588828901611bce565b60008060006060848603121561208e57600080fd5b61209784611a03565b95602085013595506040909401359392505050565b600181811c908216806120c057607f821691505b6020821081036120e057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602f908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526e195c881b9bdc88185c1c1c9bdd9959608a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016121735761217361214b565b5060010190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b808201808211156103f8576103f861214b565b6040815260006122746040830185611e78565b82810360208401526122868185611e78565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526023908201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526024908201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604082015263616e636560e01b606082015260800190565b6001600160a01b0386811682528516602082015260a0604082018190526000906123d190830186611e78565b82810360608401526123e38186611e78565b905082810360808401526123f78185611ab9565b98975050505050505050565b60006020828403121561241557600080fd5b815161081181611a49565b600060033d11156124395760046000803e5060005160e01c5b90565b600060443d101561244a5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561247957505050505090565b82850191508151818111156124915750505050505090565b843d87010160208285010111156124ab5750505050505090565b6124ba60208286010187611b0e565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612545816017850160208801611a95565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612576816028840160208801611a95565b01602801949350505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906125bc90830184611ab9565b979650505050505050565b601f82111561058f57600081815260208120601f850160051c810160208610156125ee5750805b601f850160051c820191505b81811015610d3b578281556001016125fa565b81516001600160401b0381111561262657612626611af8565b61263a8161263484546120ac565b846125c7565b602080601f83116001811461266f57600084156126575750858301515b600019600386901b1c1916600185901b178555610d3b565b600085815260208120601f198616915b8281101561269e5788860151825594840194600190910190840161267f565b50858210156126bc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008160001904831182151516156126e6576126e661214b565b500290565b6000816126fa576126fa61214b565b506000190190565b818103818111156103f8576103f861214b565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d84f746f173a737e6816e4123648488df6b8e119ec4b4fc93237fc9c098d976b64736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220cfd36f26d92e9c9eae1566679e3ea81f70e53e42b6fbaac0130e6c239bbfa4b264736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.meta.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.meta.json new file mode 100644 index 000000000..53238fc97 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC1155.meta.json @@ -0,0 +1,410 @@ +{ + "name": "TokenManagerERC1155", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.dbg.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.json new file mode 100644 index 000000000..0b3d9614d --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.json @@ -0,0 +1,880 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerERC20", + "sourceName": "contracts/schain/TokenManagers/TokenManagerERC20.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldValue", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "DepositBoxWasChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnSchain", + "type": "address" + } + ], + "name": "ERC20TokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnSchain", + "type": "address" + } + ], + "name": "ERC20TokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ERC20TokenReady", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc20OnSchain", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ERC20TokenReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetChainName", + "type": "string" + }, + { + "internalType": "address", + "name": "erc20OnMainChain", + "type": "address" + }, + { + "internalType": "address", + "name": "erc20OnSchain", + "type": "address" + } + ], + "name": "addERC20TokenByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20OnChain", + "name": "", + "type": "address" + } + ], + "name": "addedClones", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "clonesErc20", + "outputs": [ + { + "internalType": "contract ERC20OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract ICommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deprecatedClonesErc20", + "outputs": [ + { + "internalType": "contract ERC20OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exitToMainERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract ITokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "name": "totalSupplyOnMainnet", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferToSchainERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "transferredAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50615f75806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620002555760003560e01c80636d6112861162000149578063babc4a3311620000c7578063d547741f1162000086578063d547741f14620005da578063dec2deb614620005f1578063eafd15c81462000606578063edcc12b5146200061d578063f429e383146200063457600080fd5b8063babc4a33146200053f578063c0e312dc146200056d578063ca15c8731462000584578063cb703bff146200059b578063cc5b715b14620005b257600080fd5b80639010d07c11620001145780639010d07c14620004d857806391d1485414620004ef578063a217fddf1462000506578063aebaaca9146200050f578063b9581c50146200053557600080fd5b80636d61128614620004825780636d6c68e614620004965780638504950614620004aa578063884cee5a14620004c157600080fd5b806339927cf911620001d757806350f4428011620001a257806350f4428014620003d3578063510d8a5814620004095780635573b8b6146200044057806368eb202214620004545780636ce681d2146200046b57600080fd5b806339927cf9146200036f5780633b690b6b14620003865780633fa194ce1462000390578063467a5d8114620003a757600080fd5b8063248a9ca31162000224578063248a9ca314620002ee57806328c5e18214620003235780632dc151de146200032d5780632f2ff15d146200034157806336568abe146200035857600080fd5b806301ffc9a7146200025a578063029996b814620002865780630b885ac314620002925780630f1a8f7414620002a9575b600080fd5b620002716200026b36600462003434565b62000657565b60405190151581526020015b60405180910390f35b6200029062000685565b005b62000290620002a336600462003570565b620006dd565b620002d5620002ba36600462003605565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016200027d565b62000314620002ff36600462003605565b60009081526065602052604090206001015490565b6040519081526020016200027d565b62000314620006f3565b60ca54620002d5906001600160a01b031681565b62000290620003523660046200361f565b6200073e565b62000290620003693660046200361f565b6200076c565b620002716200038036600462003696565b620007ee565b6200031460cc5481565b6200031460008051602062005f2083398151915281565b620002d5620003b8366004620036db565b60cf602052600090815260409020546001600160a01b031681565b620003fa6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516200027d91906200374f565b620002d56200041a3660046200361f565b60d26020908152600092835260408084209091529082529020546001600160a01b031681565b60c954620002d5906001600160a01b031681565b620002906200046536600462003764565b6200084b565b620002906200047c36600462003570565b6200095f565b60cd54620002d5906001600160a01b031681565b60cb54620002d5906001600160a01b031681565b62000290620004bb36600462003793565b62000bd3565b62000290620004d2366004620037f5565b62000e64565b620002d5620004e936600462003856565b62000ff1565b62000271620005003660046200361f565b62001012565b62000314600081565b6200027162000520366004620036db565b60d16020526000908152604090205460ff1681565b620002906200103d565b62000314620005503660046200361f565b60d360209081526000928352604080842090915290825290205481565b620002906200057e36600462003696565b62001086565b620003146200059536600462003605565b620011a4565b62000290620005ac36600462003879565b620011bd565b620003147ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000290620005eb3660046200361f565b62001344565b60cd546200027190600160a01b900460ff1681565b6200029062000617366004620038d5565b6200136d565b620002906200062e366004620036db565b6200173a565b6200031462000645366004620036db565b60d06020526000908152604090205481565b60006001600160e01b03198216635a05180f60e01b14806200067f57506200067f8262001856565b92915050565b620006a060008051602062005f208339815191523362001012565b620006c85760405162461bcd60e51b8152600401620006bf9062003944565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006ec85858585856200095f565b5050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000725919062003985565b6040516020818303038152906040528051906020012081565b6000828152606560205260409020600101546200075b816200188d565b6200076783836200189c565b505050565b6001600160a01b0381163314620007de5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401620006bf565b620007ea8282620018c2565b5050565b6000806001600160a01b031660ce6000858560405160200162000813929190620039a3565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200089092910162003985565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620008e357600080fd5b505af1158015620008f8573d6000803e3d6000fd5b50505050620007ea6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000932919062003985565b60408051601f19818403018152919052805160209091012060cd546001600160a01b0316843385620018e8565b600054610100900460ff1615808015620009805750600054600160ff909116105b806200099c5750303b1580156200099c575060005460ff166001145b62000a015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620006bf565b6000805460ff19166001179055801562000a25576000805461ff0019166101001790555b6001600160a01b03821662000a7d5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401620006bf565b62000a8762001e56565b62000a9460003362001ec5565b62000aaf60008051602062005f208339815191523362001ec5565b62000adb7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001ec5565b8560405160200162000aee919062003985565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562000bcb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060405133945090925062000c1f9150849060200162003985565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000c6192910162003985565b60405160208183030381529060405280519060200120810362000ce05760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b6064820152608401620006bf565b6001600160a01b03821662000d385760405162461bcd60e51b815260206004820152601a60248201527f496e636f727265637420726563656976657220616464726573730000000000006044820152606401620006bf565b600081815260ce60205260409020546001600160a01b031662000d9e5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401620006bf565b6000878760405160200162000db5929190620039a3565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000e1957600080fd5b505af115801562000e2e573d6000803e3d6000fd5b505050600082815260ce602052604090205462000e5a915082906001600160a01b0316883389620018e8565b5050505050505050565b60c9546001600160a01b0316331462000ec05760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f7879000000006044820152606401620006bf565b838360cc54821415801562000edc575062000edc828262001ed1565b62000f2a5760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f727265637400000000006044820152606401620006bf565b600062000f38858562001f5c565b90506000600282600e81111562000f535762000f53620039b3565b148062000f745750600482600e81111562000f725762000f72620039b3565b145b8062000f945750600382600e81111562000f925762000f92620039b3565b145b1562000faf5762000fa788878762001fb3565b905062000e5a565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b6044820152606401620006bf565b60008281526097602052604081206200100b90836200257f565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6200105860008051602062005f208339815191523362001012565b620010775760405162461bcd60e51b8152600401620006bf9062003944565b60cd805460ff60a01b19169055565b60ca546001600160a01b0316331480620010a85750620010a860003362001012565b620010ee5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b6044820152606401620006bf565b6000828260405160200162001105929190620039a3565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316620011845760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f742073657400000000000000006044820152606401620006bf565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206200067f906200258d565b60ca546001600160a01b0316331480620011df5750620011df60003362001012565b620012255760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b6044820152606401620006bf565b600083836040516020016200123c929190620039a3565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620012bc5760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c726561647920736574000000006044820152606401620006bf565b6001600160a01b038216620013145760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401620006bf565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b60008281526065602052604090206001015462001361816200188d565b620007678383620018c2565b620013997ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001012565b620013e75760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c452069732072657175697265646044820152606401620006bf565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa906200141b9087908790600401620039c9565b602060405180830381865afa15801562001439573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200145f9190620039f8565b620014a65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b6044820152606401620006bf565b6001600160a01b0381163b620014ff5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401620006bf565b806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200153e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001564919062003a1c565b15620015b35760405162461bcd60e51b815260206004820152601760248201527f546f74616c537570706c79206973206e6f74207a65726f0000000000000000006044820152606401620006bf565b60008484604051602001620015ca929190620039a3565b60408051601f198184030181529181528151602092830120600081815260d284528281206001600160a01b0388811683529452919091205490925016156200164e5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b6044820152606401620006bf565b6001600160a01b038216600090815260d1602052604090205460ff1615620016b95760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c72656164792061646465640000000000000000006044820152606401620006bf565b600081815260d2602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d1909352818420805460ff1916600117905590519192909184917f89b97f12155170c72b8eb3449d5f1ba0c6a29e5546051dc35694313b1b60741f91a45050505050565b6200174760003362001012565b620017955760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401620006bf565b6001600160a01b038116620017ed5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401620006bf565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200067f57506301ffc9a760e01b6001600160e01b03198316146200067f565b62001899813362002598565b50565b620018a8828262002607565b600082815260976020526040902062000767908262002691565b620018ce8282620026a8565b600082815260976020526040902062000767908262002712565b600085815260d2602090815260408083206001600160a01b038088168552925282205416806200198557506001600160a01b038416600090815260d16020526040902054849060ff1615620019805760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e0000000000006044820152606401620006bf565b600191505b6001600160a01b0381163b620019de5760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e00000000000000006044820152606401620006bf565b6040516370a0823160e01b815233600482015283906001600160a01b038316906370a0823190602401602060405180830381865afa15801562001a25573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a4b919062003a1c565b101562001a905760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b6044820152606401620006bf565b604051636eb1769f60e11b815233600482015230602482015283906001600160a01b0383169063dd62ed3e90604401602060405180830381865afa15801562001add573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b03919062003a1c565b101562001b645760405162461bcd60e51b815260206004820152602860248201527f5472616e73666572206973206e6f7420617070726f76656420627920746f6b6560448201526737103437b63232b960c11b6064820152608401620006bf565b600062001b7386868662002729565b9050821562001cec576040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001bae919062003985565b60405160208183030381529060405280519060200120880362001c305760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b6064820152608401620006bf565b62001c3e888333876200278a565b905062001c4d88838662002906565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd906064016020604051808303816000875af115801562001ca1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cc79190620039f8565b62001ce65760405162461bcd60e51b8152600401620006bf9062003a36565b62001de2565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd906064016020604051808303816000875af115801562001d40573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d669190620039f8565b62001d855760405162461bcd60e51b8152600401620006bf9062003a36565b604051630852cd8d60e31b8152600481018590526001600160a01b038316906342966c6890602401600060405180830381600087803b15801562001dc857600080fd5b505af115801562001ddd573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001e18908b908b90869060040162003a63565b600060405180830381600087803b15801562001e3357600080fd5b505af115801562001e48573d6000803e3d6000fd5b505050505050505050505050565b600054610100900460ff1662001ec35760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620006bf565b565b620007ea82826200189c565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001f05919062003985565b60405160208183030381529060405280519060200120831462001f4557600083815260ce60205260409020546001600160a01b038381169116146200100b565b5060cd546001600160a01b03908116911614919050565b60008062001f6d8385018562003605565b905062001f7c60208262003a98565b60000362001fa55762001f9c62001f968483818862003abb565b62001f5c565b9150506200067f565b62001f9c8385018562003afc565b60008062001fc2848462001f5c565b9050600080600062001fd5878762002944565b919450925090506000600285600e81111562001ff55762001ff5620039b3565b1462002354576000600386600e811115620020145762002014620039b3565b036200205d576000620020288a8a62002a04565b60209081015160008d815260d2835260408082206001600160a01b03808b168452945290205490911693509150620021c79050565b60006200206b8a8a62002adf565b60208082015160008e815260d2835260408082206001600160a01b03808c168452945290205490911694509250905082620021c55760cd54600160a01b900460ff16620020fb5760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c6564000000006044820152606401620006bf565b8060400151600001518160400151604001516040516200211b9062003426565b6200212892919062003b1a565b604051809103906000f08015801562002145573d6000803e3d6000fd5b5060008c815260d2602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d1909352818420805460ff191660011790559051939650909290918e917f817384d3c8c32b58342425cd864f5540355cc93dfbbfc2df8763793d2d3a5e129190a45b505b6001600160a01b038216600090815260d06020526040902054811462002203576001600160a01b038216600090815260d0602052604090208190555b60008062002276846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002249573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200226f919062003a1c565b8662002bd6565b9092509050818015620022a157506001600160a01b038416600090815260d060205260409020548111155b620022e75760405162461bcd60e51b8152602060048201526015602482015274151bdd185b081cdd5c1c1b1e48195e18d959591959605a1b6044820152606401620006bf565b6040516340c10f1960e01b81526001600160a01b038881166004830152602482018790528516906340c10f1990604401600060405180830381600087803b1580156200233257600080fd5b505af115801562002347573d6000803e3d6000fd5b5050505050505062002523565b6001600160a01b0383163b15158015620023835750600089815260d46020526040902062002383908462002c01565b620023d15760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e0000000000006044820152606401620006bf565b6040516370a0823160e01b815230600482015282906001600160a01b038516906370a0823190602401602060405180830381865afa15801562002418573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200243e919062003a1c565b1015620024815760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768206d6f6e657960801b6044820152606401620006bf565b6200248e89848462002c24565b60405163a9059cbb60e01b81526001600160a01b0385811660048301526024820184905284169063a9059cbb906044016020604051808303816000875af1158015620024de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620025049190620039f8565b620025235760405162461bcd60e51b8152600401620006bf9062003a36565b806001600160a01b0316836001600160a01b03168a7f131b32ac87206ff25b3250e2d194c4cc6d63e928ab212dbd294b03b49af27b48856040516200256a91815260200190565b60405180910390a45091979650505050505050565b60006200100b838362002c58565b60006200067f825490565b620025a4828262001012565b620007ea57620025bf816001600160a01b0316601462002c85565b620025cc83602062002c85565b604051602001620025df92919062003b43565b60408051601f198184030181529082905262461bcd60e51b8252620006bf916004016200374f565b62002613828262001012565b620007ea5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200264d3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200100b836001600160a01b03841662002e3e565b620026b4828262001012565b15620007ea5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006200100b836001600160a01b03841662002e90565b6040805160a08101825260026080820190815281526001600160a01b038086166020808401919091529085168284015260608083018590529251620027719183910162003c10565b6040516020818303038152906040529150509392505050565b606060008490506000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620027d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620027f8919062003a1c565b905080841115620028425760405162461bcd60e51b8152602060048201526013602482015272105b5bdd5b9d081a5cc81a5b98dbdc9c9958dd606a1b6044820152606401620006bf565b600087815260d4602052604081206200285c908862002c01565b9050806200289b5762002870888862002f94565b620028938787876200288287620030ad565b6200288d8862003114565b62003287565b9350620028b6565b620028b3878787620028ad87620030ad565b620032ff565b93505b866001600160a01b0316887f759c7e29aa34dec4bb9f3af86e647e11cffa0fee371049fd55e8779a2c24484e87604051620028f391815260200190565b60405180910390a3505050949350505050565b600083815260d3602090815260408083206001600160a01b0386168452909152812080548392906200293a90849062003c36565b9091555050505050565b60008060008062002956868662001f5c565b9050600281600e8111156200296f576200296f620039b3565b03620029a257600062002983878762003372565b90508060400151816020015182606001519450945094505050620029fd565b600381600e811115620029b957620029b9620039b3565b03620029ef576000620029cd878762002a04565b51604081015160208201516060909201519096509094509250620029fd915050565b6000620029cd878762002adf565b9250925092565b62002a446040805160e081018252600060c08201818152928201928352606082018190526080820181905260a08201529081908152602001600081525090565b600362002a52848462001f5c565b600e81111562002a665762002a66620039b3565b1462002ad15760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f74204552433230207472616e7366604482015272657220616e6420746f74616c20737570706c7960681b6064820152608401620006bf565b6200100b8284018462003d0f565b62002b3c6040805161010081018252600060e0820181815260608084019182526080840183905260a0840183905260c084018390529083526020808401839052845180830186528281529081019290925281840152909182015290565b600462002b4a848462001f5c565b600e81111562002b5e5762002b5e620039b3565b1462002bc85760405162461bcd60e51b815260206004820152603260248201527f4d6573736167652074797065206973206e6f74204552433230207472616e73666044820152716572207769746820746f6b656e20696e666f60701b6064820152608401620006bf565b6200100b8284018462003d7a565b6000808383018481101562002bf357600080925092505062002bfa565b6001925090505b9250929050565b6001600160a01b038116600090815260018301602052604081205415156200100b565b600083815260d3602090815260408083206001600160a01b0386168452909152812080548392906200293a90849062003e7f565b600082600001828154811062002c725762002c7262003e95565b9060005260206000200154905092915050565b6060600062002c9683600262003eab565b62002ca390600262003c36565b6001600160401b0381111562002cbd5762002cbd62003460565b6040519080825280601f01601f19166020018201604052801562002ce8576020820181803683370190505b509050600360fc1b8160008151811062002d065762002d0662003e95565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002d385762002d3862003e95565b60200101906001600160f81b031916908160001a905350600062002d5e84600262003eab565b62002d6b90600162003c36565b90505b600181111562002ded576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002da35762002da362003e95565b1a60f81b82828151811062002dbc5762002dbc62003e95565b60200101906001600160f81b031916908160001a90535060049490941c9362002de58162003ecd565b905062002d6e565b5083156200100b5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620006bf565b600081815260018301602052604081205462002e87575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200067f565b5060006200067f565b6000818152600183016020526040812054801562002f8957600062002eb760018362003e7f565b855490915060009062002ecd9060019062003e7f565b905081811462002f3957600086600001828154811062002ef15762002ef162003e95565b906000526020600020015490508087600001848154811062002f175762002f1762003e95565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002f4d5762002f4d62003ee7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200067f565b60009150506200067f565b6001600160a01b0381163b62002fed5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401620006bf565b600082815260d46020526040902062003007908262002c01565b15620030565760405162461bcd60e51b815260206004820152601d60248201527f455243323020546f6b656e2077617320616c72656164792061646465640000006044820152606401620006bf565b600082815260d46020526040902062003070908262002691565b506040516000906001600160a01b0383169084907f89b97f12155170c72b8eb3449d5f1ba0c6a29e5546051dc35694313b1b60741f908490a45050565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620030ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200067f919062003a1c565b604080516060808201835280825260006020830152918101919091526040518060600160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200317a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620031a4919081019062003efd565b8152602001836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620031e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200320e919062003f73565b60ff168152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562003255573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200327f919081019062003efd565b905292915050565b6040805161010081018252600460e0820190815260608083019182526001600160a01b03808a166080850152881660a084015260c08301879052908252602080830186905282840185905292519092620032e49183910162003f93565b60405160208183030381529060405291505095945050505050565b6040805160e081018252600360c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a08301869052908252602080830185905292519092620033589183910162004007565b604051602081830303815290604052915050949350505050565b6040805160a08101825260006080820181815282526020820181905291810182905260608101919091526002620033aa848462001f5c565b600e811115620033be57620033be620039b3565b14620034185760405162461bcd60e51b815260206004820152602260248201527f4d6573736167652074797065206973206e6f74204552433230207472616e736660448201526132b960f11b6064820152608401620006bf565b6200100b828401846200402c565b611ed4806200404c83390190565b6000602082840312156200344757600080fd5b81356001600160e01b0319811681146200100b57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200349b576200349b62003460565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620034cc57620034cc62003460565b604052919050565b60006001600160401b03821115620034f057620034f062003460565b50601f01601f191660200190565b600082601f8301126200351057600080fd5b8135620035276200352182620034d4565b620034a1565b8181528460208386010111156200353d57600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b03811681146200189957600080fd5b600080600080600060a086880312156200358957600080fd5b85356001600160401b03811115620035a057600080fd5b620035ae88828901620034fe565b9550506020860135620035c1816200355a565b93506040860135620035d3816200355a565b92506060860135620035e5816200355a565b91506080860135620035f7816200355a565b809150509295509295909350565b6000602082840312156200361857600080fd5b5035919050565b600080604083850312156200363357600080fd5b82359150602083013562003647816200355a565b809150509250929050565b60008083601f8401126200366557600080fd5b5081356001600160401b038111156200367d57600080fd5b60208301915083602082850101111562002bfa57600080fd5b60008060208385031215620036aa57600080fd5b82356001600160401b03811115620036c157600080fd5b620036cf8582860162003652565b90969095509350505050565b600060208284031215620036ee57600080fd5b81356200100b816200355a565b60005b8381101562003718578181015183820152602001620036fe565b50506000910152565b600081518084526200373b816020860160208601620036fb565b601f01601f19169290920160200192915050565b6020815260006200100b602083018462003721565b600080604083850312156200377857600080fd5b823562003785816200355a565b946020939093013593505050565b60008060008060608587031215620037aa57600080fd5b84356001600160401b03811115620037c157600080fd5b620037cf8782880162003652565b9095509350506020850135620037e5816200355a565b9396929550929360400135925050565b600080600080606085870312156200380c57600080fd5b84359350602085013562003820816200355a565b925060408501356001600160401b038111156200383c57600080fd5b6200384a8782880162003652565b95989497509550505050565b600080604083850312156200386a57600080fd5b50508035926020909101359150565b6000806000604084860312156200388f57600080fd5b83356001600160401b03811115620038a657600080fd5b620038b48682870162003652565b9094509250506020840135620038ca816200355a565b809150509250925092565b60008060008060608587031215620038ec57600080fd5b84356001600160401b038111156200390357600080fd5b620039118782880162003652565b909550935050602085013562003927816200355a565b9150604085013562003939816200355a565b939692955090935050565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b6000825162003999818460208701620036fb565b9190910192915050565b8183823760009101908152919050565b634e487b7160e01b600052602160045260246000fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60006020828403121562003a0b57600080fd5b815180151581146200100b57600080fd5b60006020828403121562003a2f57600080fd5b5051919050565b602080825260139082015272151c985b9cd9995c881dd85cc819985a5b1959606a1b604082015260600190565b8381526001600160a01b038316602082015260606040820181905260009062003a8f9083018462003721565b95945050505050565b60008262003ab657634e487b7160e01b600052601260045260246000fd5b500690565b6000808585111562003acc57600080fd5b8386111562003ada57600080fd5b5050820193919092039150565b8035600f811062003af757600080fd5b919050565b60006020828403121562003b0f57600080fd5b6200100b8262003ae7565b60408152600062003b2f604083018562003721565b828103602084015262003a8f818562003721565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162003b7d816017850160208801620036fb565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162003bb0816028840160208801620036fb565b01602801949350505050565b805151600f811062003bde57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b039081169184019190915260408083015190911690830152606090810151910152565b608081016200067f828462003bbc565b634e487b7160e01b600052601160045260246000fd5b808201808211156200067f576200067f62003c20565b6000818303608081121562003c6057600080fd5b604051608081016001600160401b03828210818311171562003c865762003c8662003460565b81604052829450602084121562003c9c57600080fd5b60a083019350818410818511171562003cb95762003cb962003460565b508260405262003cc98562003ae7565b815281526020840135915062003cdf826200355a565b8160208201526040840135915062003cf7826200355a565b81604082015260608401356060820152505092915050565b600060a0828403121562003d2257600080fd5b604051604081018181106001600160401b038211171562003d475762003d4762003460565b60405262003d56848462003c4c565b815260809290920135602083015250919050565b60ff811681146200189957600080fd5b60006020828403121562003d8d57600080fd5b81356001600160401b038082111562003da557600080fd5b9083019060c0828603121562003dba57600080fd5b62003dc462003476565b62003dd0868462003c4c565b81526080830135602082015260a08301358281111562003def57600080fd5b92909201916060838703121562003e0557600080fd5b62003e0f62003476565b83358381111562003e1f57600080fd5b62003e2d88828701620034fe565b825250602084013562003e408162003d6a565b602082015260408401358381111562003e5857600080fd5b62003e6688828701620034fe565b6040830152508060408301525080935050505092915050565b818103818111156200067f576200067f62003c20565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161562003ec85762003ec862003c20565b500290565b60008162003edf5762003edf62003c20565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006020828403121562003f1057600080fd5b81516001600160401b0381111562003f2757600080fd5b8201601f8101841362003f3957600080fd5b805162003f4a6200352182620034d4565b81815285602083850101111562003f6057600080fd5b62003a8f826020830160208601620036fb565b60006020828403121562003f8657600080fd5b81516200100b8162003d6a565b6020815262003fa760208201835162003bbc565b602082015160a08201526000604083015160c0808401528051606060e085015262003fd761014085018262003721565b602083015160ff1661010086015260409092015184830360df190161012086015291905062003a8f818362003721565b600060a0820190506200401c82845162003bbc565b6020830151608083015292915050565b6000608082840312156200403f57600080fd5b6200100b838362003c4c56fe60806040523480156200001157600080fd5b5060405162001ed438038062001ed48339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b620007211760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b620007301760201c565b6200013e83836200024660201b620007591760201c565b62000153620001e860201b620007301760201c565b6200016e60008051602062001eb483398151915280620002b2565b6200018960008051602062001eb483398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60cc62000373838262000698565b5060cd62000382828262000698565b505050565b6200039e8282620003c560201b6200078a1760201c565b6000828152609760209081526040909120620003829183906200081062000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61172080620007746000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d7146102ef578063a9059cbb14610302578063ca15c87314610315578063d539139314610328578063d547741f1461034f578063dd62ed3e1461036257600080fd5b806370a082311461026557806379cc67901461028e5780639010d07c146102a157806391d14854146102cc57806395d89b41146102df578063a217fddf146102e757600080fd5b80632f2ff15d116101155780632f2ff15d146101f5578063313ce5671461020a57806336568abe14610219578063395093511461022c57806340c10f191461023f57806342966c681461025257600080fd5b806301ffc9a71461015d57806306fdde0314610185578063095ea7b31461019a57806318160ddd146101ad57806323b872dd146101bf578063248a9ca3146101d2575b600080fd5b61017061016b36600461127f565b610375565b60405190151581526020015b60405180910390f35b61018d6103a0565b60405161017c91906112cd565b6101706101a836600461131c565b610432565b60cb545b60405190815260200161017c565b6101706101cd366004611346565b61044a565b6101b16101e0366004611382565b60009081526065602052604090206001015490565b61020861020336600461139b565b61046e565b005b6040516012815260200161017c565b61020861022736600461139b565b610498565b61017061023a36600461131c565b61051b565b61020861024d36600461131c565b61053d565b610208610260366004611382565b6105b6565b6101b16102733660046113c7565b6001600160a01b0316600090815260c9602052604090205490565b61020861029c36600461131c565b6105c3565b6102b46102af3660046113e2565b6105d8565b6040516001600160a01b03909116815260200161017c565b6101706102da36600461139b565b6105f7565b61018d610622565b6101b1600081565b6101706102fd36600461131c565b610631565b61017061031036600461131c565b6106ac565b6101b1610323366004611382565b6106ba565b6101b17f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61020861035d36600461139b565b6106d1565b6101b1610370366004611404565b6106f6565b60006001600160e01b03198216635a05180f60e01b148061039a575061039a82610825565b92915050565b606060cc80546103af9061142e565b80601f01602080910402602001604051908101604052809291908181526020018280546103db9061142e565b80156104285780601f106103fd57610100808354040283529160200191610428565b820191906000526020600020905b81548152906001019060200180831161040b57829003601f168201915b5050505050905090565b60003361044081858561085a565b5060019392505050565b60003361045885828561097e565b6104638585856109f8565b506001949350505050565b60008281526065602052604090206001015461048981610bc6565b6104938383610bd0565b505050565b6001600160a01b038116331461050d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105178282610bf2565b5050565b60003361044081858561052e83836106f6565b610538919061147e565b61085a565b6105677f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336105f7565b6105ac5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610504565b6105178282610c14565b6105c03382610cf3565b50565b6105ce82338361097e565b6105178282610cf3565b60008281526097602052604081206105f09083610e41565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd80546103af9061142e565b6000338161063f82866106f6565b90508381101561069f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610504565b610463828686840361085a565b6000336104408185856109f8565b600081815260976020526040812061039a90610e4d565b6000828152606560205260409020600101546106ec81610bc6565b6104938383610bf2565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6001600160a01b03163b151590565b600054610100900460ff166107575760405162461bcd60e51b815260040161050490611491565b565b600054610100900460ff166107805760405162461bcd60e51b815260040161050490611491565b6105178282610e57565b61079482826105f7565b6105175760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107cc3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006105f0836001600160a01b038416610e97565b60006001600160e01b03198216637965db0b60e01b148061039a57506301ffc9a760e01b6001600160e01b031983161461039a565b6001600160a01b0383166108bc5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610504565b6001600160a01b03821661091d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610504565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061098a84846106f6565b905060001981146109f257818110156109e55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610504565b6109f2848484840361085a565b50505050565b6001600160a01b038316610a5c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610504565b6001600160a01b038216610abe5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610504565b6001600160a01b038316600090815260c9602052604090205481811015610b365760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610504565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610b6d90849061147e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610bb991815260200190565b60405180910390a36109f2565b6105c08133610ee6565b610bda828261078a565b60008281526097602052604090206104939082610810565b610bfc8282610f4a565b60008281526097602052604090206104939082610fb1565b6001600160a01b038216610c6a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610504565b8060cb6000828254610c7c919061147e565b90915550506001600160a01b038216600090815260c9602052604081208054839290610ca990849061147e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610d535760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610504565b6001600160a01b038216600090815260c9602052604090205481811015610dc75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610504565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610df69084906114dc565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006105f08383610fc6565b600061039a825490565b600054610100900460ff16610e7e5760405162461bcd60e51b815260040161050490611491565b60cc610e8a8382611553565b5060cd6104938282611553565b6000818152600183016020526040812054610ede5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561039a565b50600061039a565b610ef082826105f7565b61051757610f08816001600160a01b03166014610ff0565b610f13836020610ff0565b604051602001610f24929190611613565b60408051601f198184030181529082905262461bcd60e51b8252610504916004016112cd565b610f5482826105f7565b156105175760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006105f0836001600160a01b03841661118c565b6000826000018281548110610fdd57610fdd611688565b9060005260206000200154905092915050565b60606000610fff83600261169e565b61100a90600261147e565b67ffffffffffffffff811115611022576110226114ef565b6040519080825280601f01601f19166020018201604052801561104c576020820181803683370190505b509050600360fc1b8160008151811061106757611067611688565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061109657611096611688565b60200101906001600160f81b031916908160001a90535060006110ba84600261169e565b6110c590600161147e565b90505b600181111561113d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110f9576110f9611688565b1a60f81b82828151811061110f5761110f611688565b60200101906001600160f81b031916908160001a90535060049490941c93611136816116bd565b90506110c8565b5083156105f05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610504565b600081815260018301602052604081205480156112755760006111b06001836114dc565b85549091506000906111c4906001906114dc565b90508181146112295760008660000182815481106111e4576111e4611688565b906000526020600020015490508087600001848154811061120757611207611688565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061123a5761123a6116d4565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061039a565b600091505061039a565b60006020828403121561129157600080fd5b81356001600160e01b0319811681146105f057600080fd5b60005b838110156112c45781810151838201526020016112ac565b50506000910152565b60208152600082518060208401526112ec8160408501602087016112a9565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461131757600080fd5b919050565b6000806040838503121561132f57600080fd5b61133883611300565b946020939093013593505050565b60008060006060848603121561135b57600080fd5b61136484611300565b925061137260208501611300565b9150604084013590509250925092565b60006020828403121561139457600080fd5b5035919050565b600080604083850312156113ae57600080fd5b823591506113be60208401611300565b90509250929050565b6000602082840312156113d957600080fd5b6105f082611300565b600080604083850312156113f557600080fd5b50508035926020909101359150565b6000806040838503121561141757600080fd5b61142083611300565b91506113be60208401611300565b600181811c9082168061144257607f821691505b60208210810361146257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561039a5761039a611468565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8181038181111561039a5761039a611468565b634e487b7160e01b600052604160045260246000fd5b601f82111561049357600081815260208120601f850160051c8101602086101561152c5750805b601f850160051c820191505b8181101561154b57828155600101611538565b505050505050565b815167ffffffffffffffff81111561156d5761156d6114ef565b6115818161157b845461142e565b84611505565b602080601f8311600181146115b6576000841561159e5750858301515b600019600386901b1c1916600185901b17855561154b565b600085815260208120601f198616915b828110156115e5578886015182559484019460019091019084016115c6565b50858210156116035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161164b8160178501602088016112a9565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161167c8160288401602088016112a9565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156116b8576116b8611468565b500290565b6000816116cc576116cc611468565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212202f9e9a6091230d31a1843f8d7bfacf836c46ab8210847934d487741528853dc964736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220ebd127e06d6e3b7c0f4a5296b0482b2d6560427a745fbe044dbd8c0b29cd3a9e64736f6c63430008100033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002555760003560e01c80636d6112861162000149578063babc4a3311620000c7578063d547741f1162000086578063d547741f14620005da578063dec2deb614620005f1578063eafd15c81462000606578063edcc12b5146200061d578063f429e383146200063457600080fd5b8063babc4a33146200053f578063c0e312dc146200056d578063ca15c8731462000584578063cb703bff146200059b578063cc5b715b14620005b257600080fd5b80639010d07c11620001145780639010d07c14620004d857806391d1485414620004ef578063a217fddf1462000506578063aebaaca9146200050f578063b9581c50146200053557600080fd5b80636d61128614620004825780636d6c68e614620004965780638504950614620004aa578063884cee5a14620004c157600080fd5b806339927cf911620001d757806350f4428011620001a257806350f4428014620003d3578063510d8a5814620004095780635573b8b6146200044057806368eb202214620004545780636ce681d2146200046b57600080fd5b806339927cf9146200036f5780633b690b6b14620003865780633fa194ce1462000390578063467a5d8114620003a757600080fd5b8063248a9ca31162000224578063248a9ca314620002ee57806328c5e18214620003235780632dc151de146200032d5780632f2ff15d146200034157806336568abe146200035857600080fd5b806301ffc9a7146200025a578063029996b814620002865780630b885ac314620002925780630f1a8f7414620002a9575b600080fd5b620002716200026b36600462003434565b62000657565b60405190151581526020015b60405180910390f35b6200029062000685565b005b62000290620002a336600462003570565b620006dd565b620002d5620002ba36600462003605565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016200027d565b62000314620002ff36600462003605565b60009081526065602052604090206001015490565b6040519081526020016200027d565b62000314620006f3565b60ca54620002d5906001600160a01b031681565b62000290620003523660046200361f565b6200073e565b62000290620003693660046200361f565b6200076c565b620002716200038036600462003696565b620007ee565b6200031460cc5481565b6200031460008051602062005f2083398151915281565b620002d5620003b8366004620036db565b60cf602052600090815260409020546001600160a01b031681565b620003fa6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516200027d91906200374f565b620002d56200041a3660046200361f565b60d26020908152600092835260408084209091529082529020546001600160a01b031681565b60c954620002d5906001600160a01b031681565b620002906200046536600462003764565b6200084b565b620002906200047c36600462003570565b6200095f565b60cd54620002d5906001600160a01b031681565b60cb54620002d5906001600160a01b031681565b62000290620004bb36600462003793565b62000bd3565b62000290620004d2366004620037f5565b62000e64565b620002d5620004e936600462003856565b62000ff1565b62000271620005003660046200361f565b62001012565b62000314600081565b6200027162000520366004620036db565b60d16020526000908152604090205460ff1681565b620002906200103d565b62000314620005503660046200361f565b60d360209081526000928352604080842090915290825290205481565b620002906200057e36600462003696565b62001086565b620003146200059536600462003605565b620011a4565b62000290620005ac36600462003879565b620011bd565b620003147ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000290620005eb3660046200361f565b62001344565b60cd546200027190600160a01b900460ff1681565b6200029062000617366004620038d5565b6200136d565b620002906200062e366004620036db565b6200173a565b6200031462000645366004620036db565b60d06020526000908152604090205481565b60006001600160e01b03198216635a05180f60e01b14806200067f57506200067f8262001856565b92915050565b620006a060008051602062005f208339815191523362001012565b620006c85760405162461bcd60e51b8152600401620006bf9062003944565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006ec85858585856200095f565b5050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000725919062003985565b6040516020818303038152906040528051906020012081565b6000828152606560205260409020600101546200075b816200188d565b6200076783836200189c565b505050565b6001600160a01b0381163314620007de5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401620006bf565b620007ea8282620018c2565b5050565b6000806001600160a01b031660ce6000858560405160200162000813929190620039a3565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200089092910162003985565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620008e357600080fd5b505af1158015620008f8573d6000803e3d6000fd5b50505050620007ea6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000932919062003985565b60408051601f19818403018152919052805160209091012060cd546001600160a01b0316843385620018e8565b600054610100900460ff1615808015620009805750600054600160ff909116105b806200099c5750303b1580156200099c575060005460ff166001145b62000a015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620006bf565b6000805460ff19166001179055801562000a25576000805461ff0019166101001790555b6001600160a01b03821662000a7d5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401620006bf565b62000a8762001e56565b62000a9460003362001ec5565b62000aaf60008051602062005f208339815191523362001ec5565b62000adb7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001ec5565b8560405160200162000aee919062003985565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562000bcb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060405133945090925062000c1f9150849060200162003985565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000c6192910162003985565b60405160208183030381529060405280519060200120810362000ce05760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b6064820152608401620006bf565b6001600160a01b03821662000d385760405162461bcd60e51b815260206004820152601a60248201527f496e636f727265637420726563656976657220616464726573730000000000006044820152606401620006bf565b600081815260ce60205260409020546001600160a01b031662000d9e5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401620006bf565b6000878760405160200162000db5929190620039a3565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000e1957600080fd5b505af115801562000e2e573d6000803e3d6000fd5b505050600082815260ce602052604090205462000e5a915082906001600160a01b0316883389620018e8565b5050505050505050565b60c9546001600160a01b0316331462000ec05760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f7879000000006044820152606401620006bf565b838360cc54821415801562000edc575062000edc828262001ed1565b62000f2a5760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f727265637400000000006044820152606401620006bf565b600062000f38858562001f5c565b90506000600282600e81111562000f535762000f53620039b3565b148062000f745750600482600e81111562000f725762000f72620039b3565b145b8062000f945750600382600e81111562000f925762000f92620039b3565b145b1562000faf5762000fa788878762001fb3565b905062000e5a565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b6044820152606401620006bf565b60008281526097602052604081206200100b90836200257f565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6200105860008051602062005f208339815191523362001012565b620010775760405162461bcd60e51b8152600401620006bf9062003944565b60cd805460ff60a01b19169055565b60ca546001600160a01b0316331480620010a85750620010a860003362001012565b620010ee5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b6044820152606401620006bf565b6000828260405160200162001105929190620039a3565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316620011845760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f742073657400000000000000006044820152606401620006bf565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206200067f906200258d565b60ca546001600160a01b0316331480620011df5750620011df60003362001012565b620012255760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b6044820152606401620006bf565b600083836040516020016200123c929190620039a3565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620012bc5760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c726561647920736574000000006044820152606401620006bf565b6001600160a01b038216620013145760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401620006bf565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b60008281526065602052604090206001015462001361816200188d565b620007678383620018c2565b620013997ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001012565b620013e75760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c452069732072657175697265646044820152606401620006bf565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa906200141b9087908790600401620039c9565b602060405180830381865afa15801562001439573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200145f9190620039f8565b620014a65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b6044820152606401620006bf565b6001600160a01b0381163b620014ff5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401620006bf565b806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200153e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001564919062003a1c565b15620015b35760405162461bcd60e51b815260206004820152601760248201527f546f74616c537570706c79206973206e6f74207a65726f0000000000000000006044820152606401620006bf565b60008484604051602001620015ca929190620039a3565b60408051601f198184030181529181528151602092830120600081815260d284528281206001600160a01b0388811683529452919091205490925016156200164e5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b6044820152606401620006bf565b6001600160a01b038216600090815260d1602052604090205460ff1615620016b95760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c72656164792061646465640000000000000000006044820152606401620006bf565b600081815260d2602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d1909352818420805460ff1916600117905590519192909184917f89b97f12155170c72b8eb3449d5f1ba0c6a29e5546051dc35694313b1b60741f91a45050505050565b6200174760003362001012565b620017955760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401620006bf565b6001600160a01b038116620017ed5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401620006bf565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200067f57506301ffc9a760e01b6001600160e01b03198316146200067f565b62001899813362002598565b50565b620018a8828262002607565b600082815260976020526040902062000767908262002691565b620018ce8282620026a8565b600082815260976020526040902062000767908262002712565b600085815260d2602090815260408083206001600160a01b038088168552925282205416806200198557506001600160a01b038416600090815260d16020526040902054849060ff1615620019805760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e0000000000006044820152606401620006bf565b600191505b6001600160a01b0381163b620019de5760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e00000000000000006044820152606401620006bf565b6040516370a0823160e01b815233600482015283906001600160a01b038316906370a0823190602401602060405180830381865afa15801562001a25573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a4b919062003a1c565b101562001a905760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b6044820152606401620006bf565b604051636eb1769f60e11b815233600482015230602482015283906001600160a01b0383169063dd62ed3e90604401602060405180830381865afa15801562001add573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b03919062003a1c565b101562001b645760405162461bcd60e51b815260206004820152602860248201527f5472616e73666572206973206e6f7420617070726f76656420627920746f6b6560448201526737103437b63232b960c11b6064820152608401620006bf565b600062001b7386868662002729565b9050821562001cec576040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001bae919062003985565b60405160208183030381529060405280519060200120880362001c305760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b6064820152608401620006bf565b62001c3e888333876200278a565b905062001c4d88838662002906565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd906064016020604051808303816000875af115801562001ca1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cc79190620039f8565b62001ce65760405162461bcd60e51b8152600401620006bf9062003a36565b62001de2565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd906064016020604051808303816000875af115801562001d40573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d669190620039f8565b62001d855760405162461bcd60e51b8152600401620006bf9062003a36565b604051630852cd8d60e31b8152600481018590526001600160a01b038316906342966c6890602401600060405180830381600087803b15801562001dc857600080fd5b505af115801562001ddd573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001e18908b908b90869060040162003a63565b600060405180830381600087803b15801562001e3357600080fd5b505af115801562001e48573d6000803e3d6000fd5b505050505050505050505050565b600054610100900460ff1662001ec35760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620006bf565b565b620007ea82826200189c565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001f05919062003985565b60405160208183030381529060405280519060200120831462001f4557600083815260ce60205260409020546001600160a01b038381169116146200100b565b5060cd546001600160a01b03908116911614919050565b60008062001f6d8385018562003605565b905062001f7c60208262003a98565b60000362001fa55762001f9c62001f968483818862003abb565b62001f5c565b9150506200067f565b62001f9c8385018562003afc565b60008062001fc2848462001f5c565b9050600080600062001fd5878762002944565b919450925090506000600285600e81111562001ff55762001ff5620039b3565b1462002354576000600386600e811115620020145762002014620039b3565b036200205d576000620020288a8a62002a04565b60209081015160008d815260d2835260408082206001600160a01b03808b168452945290205490911693509150620021c79050565b60006200206b8a8a62002adf565b60208082015160008e815260d2835260408082206001600160a01b03808c168452945290205490911694509250905082620021c55760cd54600160a01b900460ff16620020fb5760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c6564000000006044820152606401620006bf565b8060400151600001518160400151604001516040516200211b9062003426565b6200212892919062003b1a565b604051809103906000f08015801562002145573d6000803e3d6000fd5b5060008c815260d2602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d1909352818420805460ff191660011790559051939650909290918e917f817384d3c8c32b58342425cd864f5540355cc93dfbbfc2df8763793d2d3a5e129190a45b505b6001600160a01b038216600090815260d06020526040902054811462002203576001600160a01b038216600090815260d0602052604090208190555b60008062002276846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002249573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200226f919062003a1c565b8662002bd6565b9092509050818015620022a157506001600160a01b038416600090815260d060205260409020548111155b620022e75760405162461bcd60e51b8152602060048201526015602482015274151bdd185b081cdd5c1c1b1e48195e18d959591959605a1b6044820152606401620006bf565b6040516340c10f1960e01b81526001600160a01b038881166004830152602482018790528516906340c10f1990604401600060405180830381600087803b1580156200233257600080fd5b505af115801562002347573d6000803e3d6000fd5b5050505050505062002523565b6001600160a01b0383163b15158015620023835750600089815260d46020526040902062002383908462002c01565b620023d15760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e0000000000006044820152606401620006bf565b6040516370a0823160e01b815230600482015282906001600160a01b038516906370a0823190602401602060405180830381865afa15801562002418573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200243e919062003a1c565b1015620024815760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768206d6f6e657960801b6044820152606401620006bf565b6200248e89848462002c24565b60405163a9059cbb60e01b81526001600160a01b0385811660048301526024820184905284169063a9059cbb906044016020604051808303816000875af1158015620024de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620025049190620039f8565b620025235760405162461bcd60e51b8152600401620006bf9062003a36565b806001600160a01b0316836001600160a01b03168a7f131b32ac87206ff25b3250e2d194c4cc6d63e928ab212dbd294b03b49af27b48856040516200256a91815260200190565b60405180910390a45091979650505050505050565b60006200100b838362002c58565b60006200067f825490565b620025a4828262001012565b620007ea57620025bf816001600160a01b0316601462002c85565b620025cc83602062002c85565b604051602001620025df92919062003b43565b60408051601f198184030181529082905262461bcd60e51b8252620006bf916004016200374f565b62002613828262001012565b620007ea5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200264d3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200100b836001600160a01b03841662002e3e565b620026b4828262001012565b15620007ea5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006200100b836001600160a01b03841662002e90565b6040805160a08101825260026080820190815281526001600160a01b038086166020808401919091529085168284015260608083018590529251620027719183910162003c10565b6040516020818303038152906040529150509392505050565b606060008490506000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620027d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620027f8919062003a1c565b905080841115620028425760405162461bcd60e51b8152602060048201526013602482015272105b5bdd5b9d081a5cc81a5b98dbdc9c9958dd606a1b6044820152606401620006bf565b600087815260d4602052604081206200285c908862002c01565b9050806200289b5762002870888862002f94565b620028938787876200288287620030ad565b6200288d8862003114565b62003287565b9350620028b6565b620028b3878787620028ad87620030ad565b620032ff565b93505b866001600160a01b0316887f759c7e29aa34dec4bb9f3af86e647e11cffa0fee371049fd55e8779a2c24484e87604051620028f391815260200190565b60405180910390a3505050949350505050565b600083815260d3602090815260408083206001600160a01b0386168452909152812080548392906200293a90849062003c36565b9091555050505050565b60008060008062002956868662001f5c565b9050600281600e8111156200296f576200296f620039b3565b03620029a257600062002983878762003372565b90508060400151816020015182606001519450945094505050620029fd565b600381600e811115620029b957620029b9620039b3565b03620029ef576000620029cd878762002a04565b51604081015160208201516060909201519096509094509250620029fd915050565b6000620029cd878762002adf565b9250925092565b62002a446040805160e081018252600060c08201818152928201928352606082018190526080820181905260a08201529081908152602001600081525090565b600362002a52848462001f5c565b600e81111562002a665762002a66620039b3565b1462002ad15760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f74204552433230207472616e7366604482015272657220616e6420746f74616c20737570706c7960681b6064820152608401620006bf565b6200100b8284018462003d0f565b62002b3c6040805161010081018252600060e0820181815260608084019182526080840183905260a0840183905260c084018390529083526020808401839052845180830186528281529081019290925281840152909182015290565b600462002b4a848462001f5c565b600e81111562002b5e5762002b5e620039b3565b1462002bc85760405162461bcd60e51b815260206004820152603260248201527f4d6573736167652074797065206973206e6f74204552433230207472616e73666044820152716572207769746820746f6b656e20696e666f60701b6064820152608401620006bf565b6200100b8284018462003d7a565b6000808383018481101562002bf357600080925092505062002bfa565b6001925090505b9250929050565b6001600160a01b038116600090815260018301602052604081205415156200100b565b600083815260d3602090815260408083206001600160a01b0386168452909152812080548392906200293a90849062003e7f565b600082600001828154811062002c725762002c7262003e95565b9060005260206000200154905092915050565b6060600062002c9683600262003eab565b62002ca390600262003c36565b6001600160401b0381111562002cbd5762002cbd62003460565b6040519080825280601f01601f19166020018201604052801562002ce8576020820181803683370190505b509050600360fc1b8160008151811062002d065762002d0662003e95565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002d385762002d3862003e95565b60200101906001600160f81b031916908160001a905350600062002d5e84600262003eab565b62002d6b90600162003c36565b90505b600181111562002ded576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002da35762002da362003e95565b1a60f81b82828151811062002dbc5762002dbc62003e95565b60200101906001600160f81b031916908160001a90535060049490941c9362002de58162003ecd565b905062002d6e565b5083156200100b5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620006bf565b600081815260018301602052604081205462002e87575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200067f565b5060006200067f565b6000818152600183016020526040812054801562002f8957600062002eb760018362003e7f565b855490915060009062002ecd9060019062003e7f565b905081811462002f3957600086600001828154811062002ef15762002ef162003e95565b906000526020600020015490508087600001848154811062002f175762002f1762003e95565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002f4d5762002f4d62003ee7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200067f565b60009150506200067f565b6001600160a01b0381163b62002fed5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401620006bf565b600082815260d46020526040902062003007908262002c01565b15620030565760405162461bcd60e51b815260206004820152601d60248201527f455243323020546f6b656e2077617320616c72656164792061646465640000006044820152606401620006bf565b600082815260d46020526040902062003070908262002691565b506040516000906001600160a01b0383169084907f89b97f12155170c72b8eb3449d5f1ba0c6a29e5546051dc35694313b1b60741f908490a45050565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620030ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200067f919062003a1c565b604080516060808201835280825260006020830152918101919091526040518060600160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200317a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620031a4919081019062003efd565b8152602001836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620031e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200320e919062003f73565b60ff168152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562003255573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200327f919081019062003efd565b905292915050565b6040805161010081018252600460e0820190815260608083019182526001600160a01b03808a166080850152881660a084015260c08301879052908252602080830186905282840185905292519092620032e49183910162003f93565b60405160208183030381529060405291505095945050505050565b6040805160e081018252600360c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a08301869052908252602080830185905292519092620033589183910162004007565b604051602081830303815290604052915050949350505050565b6040805160a08101825260006080820181815282526020820181905291810182905260608101919091526002620033aa848462001f5c565b600e811115620033be57620033be620039b3565b14620034185760405162461bcd60e51b815260206004820152602260248201527f4d6573736167652074797065206973206e6f74204552433230207472616e736660448201526132b960f11b6064820152608401620006bf565b6200100b828401846200402c565b611ed4806200404c83390190565b6000602082840312156200344757600080fd5b81356001600160e01b0319811681146200100b57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200349b576200349b62003460565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620034cc57620034cc62003460565b604052919050565b60006001600160401b03821115620034f057620034f062003460565b50601f01601f191660200190565b600082601f8301126200351057600080fd5b8135620035276200352182620034d4565b620034a1565b8181528460208386010111156200353d57600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b03811681146200189957600080fd5b600080600080600060a086880312156200358957600080fd5b85356001600160401b03811115620035a057600080fd5b620035ae88828901620034fe565b9550506020860135620035c1816200355a565b93506040860135620035d3816200355a565b92506060860135620035e5816200355a565b91506080860135620035f7816200355a565b809150509295509295909350565b6000602082840312156200361857600080fd5b5035919050565b600080604083850312156200363357600080fd5b82359150602083013562003647816200355a565b809150509250929050565b60008083601f8401126200366557600080fd5b5081356001600160401b038111156200367d57600080fd5b60208301915083602082850101111562002bfa57600080fd5b60008060208385031215620036aa57600080fd5b82356001600160401b03811115620036c157600080fd5b620036cf8582860162003652565b90969095509350505050565b600060208284031215620036ee57600080fd5b81356200100b816200355a565b60005b8381101562003718578181015183820152602001620036fe565b50506000910152565b600081518084526200373b816020860160208601620036fb565b601f01601f19169290920160200192915050565b6020815260006200100b602083018462003721565b600080604083850312156200377857600080fd5b823562003785816200355a565b946020939093013593505050565b60008060008060608587031215620037aa57600080fd5b84356001600160401b03811115620037c157600080fd5b620037cf8782880162003652565b9095509350506020850135620037e5816200355a565b9396929550929360400135925050565b600080600080606085870312156200380c57600080fd5b84359350602085013562003820816200355a565b925060408501356001600160401b038111156200383c57600080fd5b6200384a8782880162003652565b95989497509550505050565b600080604083850312156200386a57600080fd5b50508035926020909101359150565b6000806000604084860312156200388f57600080fd5b83356001600160401b03811115620038a657600080fd5b620038b48682870162003652565b9094509250506020840135620038ca816200355a565b809150509250925092565b60008060008060608587031215620038ec57600080fd5b84356001600160401b038111156200390357600080fd5b620039118782880162003652565b909550935050602085013562003927816200355a565b9150604085013562003939816200355a565b939692955090935050565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b6000825162003999818460208701620036fb565b9190910192915050565b8183823760009101908152919050565b634e487b7160e01b600052602160045260246000fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60006020828403121562003a0b57600080fd5b815180151581146200100b57600080fd5b60006020828403121562003a2f57600080fd5b5051919050565b602080825260139082015272151c985b9cd9995c881dd85cc819985a5b1959606a1b604082015260600190565b8381526001600160a01b038316602082015260606040820181905260009062003a8f9083018462003721565b95945050505050565b60008262003ab657634e487b7160e01b600052601260045260246000fd5b500690565b6000808585111562003acc57600080fd5b8386111562003ada57600080fd5b5050820193919092039150565b8035600f811062003af757600080fd5b919050565b60006020828403121562003b0f57600080fd5b6200100b8262003ae7565b60408152600062003b2f604083018562003721565b828103602084015262003a8f818562003721565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162003b7d816017850160208801620036fb565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162003bb0816028840160208801620036fb565b01602801949350505050565b805151600f811062003bde57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b039081169184019190915260408083015190911690830152606090810151910152565b608081016200067f828462003bbc565b634e487b7160e01b600052601160045260246000fd5b808201808211156200067f576200067f62003c20565b6000818303608081121562003c6057600080fd5b604051608081016001600160401b03828210818311171562003c865762003c8662003460565b81604052829450602084121562003c9c57600080fd5b60a083019350818410818511171562003cb95762003cb962003460565b508260405262003cc98562003ae7565b815281526020840135915062003cdf826200355a565b8160208201526040840135915062003cf7826200355a565b81604082015260608401356060820152505092915050565b600060a0828403121562003d2257600080fd5b604051604081018181106001600160401b038211171562003d475762003d4762003460565b60405262003d56848462003c4c565b815260809290920135602083015250919050565b60ff811681146200189957600080fd5b60006020828403121562003d8d57600080fd5b81356001600160401b038082111562003da557600080fd5b9083019060c0828603121562003dba57600080fd5b62003dc462003476565b62003dd0868462003c4c565b81526080830135602082015260a08301358281111562003def57600080fd5b92909201916060838703121562003e0557600080fd5b62003e0f62003476565b83358381111562003e1f57600080fd5b62003e2d88828701620034fe565b825250602084013562003e408162003d6a565b602082015260408401358381111562003e5857600080fd5b62003e6688828701620034fe565b6040830152508060408301525080935050505092915050565b818103818111156200067f576200067f62003c20565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161562003ec85762003ec862003c20565b500290565b60008162003edf5762003edf62003c20565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006020828403121562003f1057600080fd5b81516001600160401b0381111562003f2757600080fd5b8201601f8101841362003f3957600080fd5b805162003f4a6200352182620034d4565b81815285602083850101111562003f6057600080fd5b62003a8f826020830160208601620036fb565b60006020828403121562003f8657600080fd5b81516200100b8162003d6a565b6020815262003fa760208201835162003bbc565b602082015160a08201526000604083015160c0808401528051606060e085015262003fd761014085018262003721565b602083015160ff1661010086015260409092015184830360df190161012086015291905062003a8f818362003721565b600060a0820190506200401c82845162003bbc565b6020830151608083015292915050565b6000608082840312156200403f57600080fd5b6200100b838362003c4c56fe60806040523480156200001157600080fd5b5060405162001ed438038062001ed48339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b620007211760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b620007301760201c565b6200013e83836200024660201b620007591760201c565b62000153620001e860201b620007301760201c565b6200016e60008051602062001eb483398151915280620002b2565b6200018960008051602062001eb483398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60cc62000373838262000698565b5060cd62000382828262000698565b505050565b6200039e8282620003c560201b6200078a1760201c565b6000828152609760209081526040909120620003829183906200081062000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61172080620007746000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d7146102ef578063a9059cbb14610302578063ca15c87314610315578063d539139314610328578063d547741f1461034f578063dd62ed3e1461036257600080fd5b806370a082311461026557806379cc67901461028e5780639010d07c146102a157806391d14854146102cc57806395d89b41146102df578063a217fddf146102e757600080fd5b80632f2ff15d116101155780632f2ff15d146101f5578063313ce5671461020a57806336568abe14610219578063395093511461022c57806340c10f191461023f57806342966c681461025257600080fd5b806301ffc9a71461015d57806306fdde0314610185578063095ea7b31461019a57806318160ddd146101ad57806323b872dd146101bf578063248a9ca3146101d2575b600080fd5b61017061016b36600461127f565b610375565b60405190151581526020015b60405180910390f35b61018d6103a0565b60405161017c91906112cd565b6101706101a836600461131c565b610432565b60cb545b60405190815260200161017c565b6101706101cd366004611346565b61044a565b6101b16101e0366004611382565b60009081526065602052604090206001015490565b61020861020336600461139b565b61046e565b005b6040516012815260200161017c565b61020861022736600461139b565b610498565b61017061023a36600461131c565b61051b565b61020861024d36600461131c565b61053d565b610208610260366004611382565b6105b6565b6101b16102733660046113c7565b6001600160a01b0316600090815260c9602052604090205490565b61020861029c36600461131c565b6105c3565b6102b46102af3660046113e2565b6105d8565b6040516001600160a01b03909116815260200161017c565b6101706102da36600461139b565b6105f7565b61018d610622565b6101b1600081565b6101706102fd36600461131c565b610631565b61017061031036600461131c565b6106ac565b6101b1610323366004611382565b6106ba565b6101b17f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61020861035d36600461139b565b6106d1565b6101b1610370366004611404565b6106f6565b60006001600160e01b03198216635a05180f60e01b148061039a575061039a82610825565b92915050565b606060cc80546103af9061142e565b80601f01602080910402602001604051908101604052809291908181526020018280546103db9061142e565b80156104285780601f106103fd57610100808354040283529160200191610428565b820191906000526020600020905b81548152906001019060200180831161040b57829003601f168201915b5050505050905090565b60003361044081858561085a565b5060019392505050565b60003361045885828561097e565b6104638585856109f8565b506001949350505050565b60008281526065602052604090206001015461048981610bc6565b6104938383610bd0565b505050565b6001600160a01b038116331461050d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105178282610bf2565b5050565b60003361044081858561052e83836106f6565b610538919061147e565b61085a565b6105677f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336105f7565b6105ac5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610504565b6105178282610c14565b6105c03382610cf3565b50565b6105ce82338361097e565b6105178282610cf3565b60008281526097602052604081206105f09083610e41565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd80546103af9061142e565b6000338161063f82866106f6565b90508381101561069f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610504565b610463828686840361085a565b6000336104408185856109f8565b600081815260976020526040812061039a90610e4d565b6000828152606560205260409020600101546106ec81610bc6565b6104938383610bf2565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6001600160a01b03163b151590565b600054610100900460ff166107575760405162461bcd60e51b815260040161050490611491565b565b600054610100900460ff166107805760405162461bcd60e51b815260040161050490611491565b6105178282610e57565b61079482826105f7565b6105175760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107cc3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006105f0836001600160a01b038416610e97565b60006001600160e01b03198216637965db0b60e01b148061039a57506301ffc9a760e01b6001600160e01b031983161461039a565b6001600160a01b0383166108bc5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610504565b6001600160a01b03821661091d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610504565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061098a84846106f6565b905060001981146109f257818110156109e55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610504565b6109f2848484840361085a565b50505050565b6001600160a01b038316610a5c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610504565b6001600160a01b038216610abe5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610504565b6001600160a01b038316600090815260c9602052604090205481811015610b365760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610504565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610b6d90849061147e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610bb991815260200190565b60405180910390a36109f2565b6105c08133610ee6565b610bda828261078a565b60008281526097602052604090206104939082610810565b610bfc8282610f4a565b60008281526097602052604090206104939082610fb1565b6001600160a01b038216610c6a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610504565b8060cb6000828254610c7c919061147e565b90915550506001600160a01b038216600090815260c9602052604081208054839290610ca990849061147e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610d535760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610504565b6001600160a01b038216600090815260c9602052604090205481811015610dc75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610504565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610df69084906114dc565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006105f08383610fc6565b600061039a825490565b600054610100900460ff16610e7e5760405162461bcd60e51b815260040161050490611491565b60cc610e8a8382611553565b5060cd6104938282611553565b6000818152600183016020526040812054610ede5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561039a565b50600061039a565b610ef082826105f7565b61051757610f08816001600160a01b03166014610ff0565b610f13836020610ff0565b604051602001610f24929190611613565b60408051601f198184030181529082905262461bcd60e51b8252610504916004016112cd565b610f5482826105f7565b156105175760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006105f0836001600160a01b03841661118c565b6000826000018281548110610fdd57610fdd611688565b9060005260206000200154905092915050565b60606000610fff83600261169e565b61100a90600261147e565b67ffffffffffffffff811115611022576110226114ef565b6040519080825280601f01601f19166020018201604052801561104c576020820181803683370190505b509050600360fc1b8160008151811061106757611067611688565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061109657611096611688565b60200101906001600160f81b031916908160001a90535060006110ba84600261169e565b6110c590600161147e565b90505b600181111561113d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110f9576110f9611688565b1a60f81b82828151811061110f5761110f611688565b60200101906001600160f81b031916908160001a90535060049490941c93611136816116bd565b90506110c8565b5083156105f05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610504565b600081815260018301602052604081205480156112755760006111b06001836114dc565b85549091506000906111c4906001906114dc565b90508181146112295760008660000182815481106111e4576111e4611688565b906000526020600020015490508087600001848154811061120757611207611688565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061123a5761123a6116d4565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061039a565b600091505061039a565b60006020828403121561129157600080fd5b81356001600160e01b0319811681146105f057600080fd5b60005b838110156112c45781810151838201526020016112ac565b50506000910152565b60208152600082518060208401526112ec8160408501602087016112a9565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461131757600080fd5b919050565b6000806040838503121561132f57600080fd5b61133883611300565b946020939093013593505050565b60008060006060848603121561135b57600080fd5b61136484611300565b925061137260208501611300565b9150604084013590509250925092565b60006020828403121561139457600080fd5b5035919050565b600080604083850312156113ae57600080fd5b823591506113be60208401611300565b90509250929050565b6000602082840312156113d957600080fd5b6105f082611300565b600080604083850312156113f557600080fd5b50508035926020909101359150565b6000806040838503121561141757600080fd5b61142083611300565b91506113be60208401611300565b600181811c9082168061144257607f821691505b60208210810361146257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561039a5761039a611468565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8181038181111561039a5761039a611468565b634e487b7160e01b600052604160045260246000fd5b601f82111561049357600081815260208120601f850160051c8101602086101561152c5750805b601f850160051c820191505b8181101561154b57828155600101611538565b505050505050565b815167ffffffffffffffff81111561156d5761156d6114ef565b6115818161157b845461142e565b84611505565b602080601f8311600181146115b6576000841561159e5750858301515b600019600386901b1c1916600185901b17855561154b565b600085815260208120601f198616915b828110156115e5578886015182559484019460019091019084016115c6565b50858210156116035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161164b8160178501602088016112a9565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161167c8160288401602088016112a9565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156116b8576116b8611468565b500290565b6000816116cc576116cc611468565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212202f9e9a6091230d31a1843f8d7bfacf836c46ab8210847934d487741528853dc964736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220ebd127e06d6e3b7c0f4a5296b0482b2d6560427a745fbe044dbd8c0b29cd3a9e64736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.meta.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.meta.json new file mode 100644 index 000000000..f46078eac --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC20.meta.json @@ -0,0 +1,410 @@ +{ + "name": "TokenManagerERC20", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.dbg.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.json new file mode 100644 index 000000000..c21d5d94f --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.json @@ -0,0 +1,861 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerERC721", + "sourceName": "contracts/schain/TokenManagers/TokenManagerERC721.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldValue", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "DepositBoxWasChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "ERC721TokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "ERC721TokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721TokenReady", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721TokenReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetChainName", + "type": "string" + }, + { + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "addERC721TokenByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC721OnChain", + "name": "", + "type": "address" + } + ], + "name": "addedClones", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "clonesErc721", + "outputs": [ + { + "internalType": "contract ERC721OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract ICommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deprecatedClonesErc721", + "outputs": [ + { + "internalType": "contract ERC721OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "exitToMainERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract ITokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferToSchainERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transferredAmount", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50616425806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620002495760003560e01c80636d611286116200013d578063b9581c5011620000bb578063cb703bff1162000086578063cb703bff14620005a6578063cc5b715b14620005bd578063d547741f14620005e5578063dec2deb614620005fc578063edcc12b5146200061157600080fd5b8063b9581c501462000537578063c0e312dc1462000541578063ca15c8731462000558578063ca99be02146200056f57600080fd5b80639010d07c11620001085780639010d07c14620004ae57806391d1485414620004c5578063a217fddf14620004dc578063aebaaca914620004e5578063b4a0522b146200050b57600080fd5b80636d61128614620004585780636d6c68e6146200046c5780636e81ae281462000480578063884cee5a146200049757600080fd5b80632f2ff15d11620001cb5780633fa194ce11620001965780633fa194ce14620003c957806350f4428014620003e05780635573b8b61462000416578063680ae2fe146200042a5780636ce681d2146200044157600080fd5b80632f2ff15d146200037a57806336568abe146200039157806339927cf914620003a85780633b690b6b14620003bf57600080fd5b80630f1a8f7411620002185780630f1a8f7414620002da5780631e0594e3146200031f578063248a9ca3146200033657806328c5e182146200035c5780632dc151de146200036657600080fd5b806301ffc9a7146200024e578063029996b8146200027a5780630b6c672314620002865780630b885ac314620002c3575b600080fd5b620002656200025f36600462002e6b565b62000628565b60405190151581526020015b60405180910390f35b6200028462000656565b005b620002b46200029736600462002ead565b60d260209081526000928352604080842090915290825290205481565b60405190815260200162000271565b62000284620002d436600462002fd6565b620006ae565b62000306620002eb3660046200306b565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200162000271565b6200028462000330366004620030d0565b620006c4565b620002b4620003473660046200306b565b60009081526065602052604090206001015490565b620002b462000955565b60ca5462000306906001600160a01b031681565b620002846200038b36600462003132565b620009a0565b62000284620003a236600462003132565b620009ce565b62000265620003b936600462003165565b62000a50565b620002b460cc5481565b620002b4600080516020620063d083398151915281565b620004076040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002719190620031fe565b60c95462000306906001600160a01b031681565b620002846200043b36600462003213565b62000aad565b620002846200045236600462002fd6565b62000dc6565b60cd5462000306906001600160a01b031681565b60cb5462000306906001600160a01b031681565b620002846200049136600462002ead565b6200103a565b62000284620004a836600462003282565b6200114e565b62000306620004bf366004620032e3565b620012bb565b62000265620004d636600462003132565b620012dc565b620002b4600081565b62000265620004f636600462003306565b60d06020526000908152604090205460ff1681565b620003066200051c36600462003306565b60cf602052600090815260409020546001600160a01b031681565b6200028462001307565b620002846200055236600462003165565b62001350565b620002b4620005693660046200306b565b6200146e565b620003066200058036600462003132565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b62000284620005b736600462003326565b62001487565b620002b47ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000284620005f636600462003132565b6200160e565b60cd546200026590600160a01b900460ff1681565b620002846200062236600462003306565b62001637565b60006001600160e01b03198216635a05180f60e01b1480620006505750620006508262001753565b92915050565b62000671600080516020620063d083398151915233620012dc565b620006995760405162461bcd60e51b8152600401620006909062003382565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006bd858585858562000dc6565b5050505050565b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040513394509092506200071091508490602001620033c3565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000752929101620033c3565b604051602081830303815290604052805190602001208103620007d15760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606482015260840162000690565b6001600160a01b038216620008295760405162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656365697665722061646472657373000000000000604482015260640162000690565b600081815260ce60205260409020546001600160a01b03166200088f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b60008787604051602001620008a6929190620033e1565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b1580156200090a57600080fd5b505af11580156200091f573d6000803e3d6000fd5b505050600082815260ce60205260409020546200094b915082906001600160a01b03168833896200178a565b5050505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009879190620033c3565b6040516020818303038152906040528051906020012081565b600082815260656020526040902060010154620009bd8162001bd6565b620009c9838362001be5565b505050565b6001600160a01b038116331462000a405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840162000690565b62000a4c828262001c0b565b5050565b6000806001600160a01b031660ce6000858560405160200162000a75929190620033e1565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b62000ad97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012dc565b62000b275760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604482015260640162000690565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9062000b5b9087908790600401620033f1565b602060405180830381865afa15801562000b79573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b9f919062003420565b62000be65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b604482015260640162000690565b6001600160a01b0381163b62000c3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b6000848460405160200162000c56929190620033e1565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b03888116835294529190912054909250161562000cda5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b604482015260640162000690565b6001600160a01b038216600090815260d0602052604090205460ff161562000d455760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c7265616479206164646564000000000000000000604482015260640162000690565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c91a45050505050565b600054610100900460ff161580801562000de75750600054600160ff909116105b8062000e035750303b15801562000e03575060005460ff166001145b62000e685760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000690565b6000805460ff19166001179055801562000e8c576000805461ff0019166101001790555b6001600160a01b03821662000ee45760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b62000eee62001c31565b62000efb60003362001ca0565b62000f16600080516020620063d08339815191523362001ca0565b62000f427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001ca0565b8560405160200162000f559190620033c3565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562001032576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200107f929101620033c3565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620010d257600080fd5b505af1158015620010e7573d6000803e3d6000fd5b5050505062000a4c6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620011219190620033c3565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168433856200178a565b60c9546001600160a01b03163314620011aa5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604482015260640162000690565b838360cc548214158015620011c65750620011c6828262001cac565b620012145760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f72726563740000000000604482015260640162000690565b600062001222858562001d37565b90506000600682600e8111156200123d576200123d62003444565b14806200125e5750600582600e8111156200125c576200125c62003444565b145b1562001279576200127188878762001d8e565b90506200094b565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604482015260640162000690565b6000828152609760205260408120620012d59083620022b2565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b62001322600080516020620063d083398151915233620012dc565b620013415760405162461bcd60e51b8152600401620006909062003382565b60cd805460ff60a01b19169055565b60ca546001600160a01b031633148062001372575062001372600033620012dc565b620013b85760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b60008282604051602001620013cf929190620033e1565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b03166200144e5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604482015260640162000690565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206200065090620022c0565b60ca546001600160a01b0316331480620014a95750620014a9600033620012dc565b620014ef5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b6000838360405160200162001506929190620033e1565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620015865760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604482015260640162000690565b6001600160a01b038216620015de5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b6000828152606560205260409020600101546200162b8162001bd6565b620009c9838362001c0b565b62001644600033620012dc565b620016925760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604482015260640162000690565b6001600160a01b038116620016ea5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200065057506301ffc9a760e01b6001600160e01b031983161462000650565b600085815260d1602090815260408083206001600160a01b038088168552925282205416806200182757506001600160a01b038416600090815260d06020526040902054849060ff1615620018225760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b600191505b6001600160a01b0381163b620018805760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604482015260640162000690565b60405163020604bf60e21b81526004810184905230906001600160a01b0383169063081812fc90602401602060405180830381865afa158015620018c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018ee91906200345a565b6001600160a01b031614620019465760405162461bcd60e51b815260206004820152601860248201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604482015260640162000690565b600062001955868686620022cb565b9050821562001a9d576040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620019909190620033c3565b60405160208183030381529060405280519060200120880362001a125760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606482015260840162000690565b62001a20888333876200232c565b905062001a2f888386620023dc565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001a7e57600080fd5b505af115801562001a93573d6000803e3d6000fd5b5050505062001b62565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001aec57600080fd5b505af115801562001b01573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018790526001600160a01b03851692506342966c689150602401600060405180830381600087803b15801562001b4857600080fd5b505af115801562001b5d573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001b98908b908b9086906004016200347a565b600060405180830381600087803b15801562001bb357600080fd5b505af115801562001bc8573d6000803e3d6000fd5b505050505050505050505050565b62001be2813362002484565b50565b62001bf18282620024f3565b6000828152609760205260409020620009c990826200257d565b62001c17828262002594565b6000828152609760205260409020620009c99082620025fe565b600054610100900460ff1662001c9e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000690565b565b62000a4c828262001be5565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001ce09190620033c3565b60405160208183030381529060405280519060200120831462001d2057600083815260ce60205260409020546001600160a01b03838116911614620012d5565b5060cd546001600160a01b03908116911614919050565b60008062001d48838501856200306b565b905062001d57602082620034af565b60000362001d805762001d7762001d7184838188620034d2565b62001d37565b91505062000650565b62001d778385018562003513565b60008062001d9d848462001d37565b90506000808080600585600e81111562001dbb5762001dbb62003444565b0362001e1557600062001dcf898962002615565b60408082015160208084015160609094015160008f815260d183528481206001600160a01b0380881683529352939093205491985092965090945016915062001fcd9050565b600062001e238989620026ca565b905080600001516040015194508060000151602001519350806000015160600151925060d160008b81526020019081526020016000206000856001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b03160362001fcb5760cd54600160a01b900460ff1662001f085760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604482015260640162000690565b602080820151805191015160405162001f219062002e06565b62001f2e92919062003531565b604051809103906000f08015801562001f4b573d6000803e3d6000fd5b5060008b815260d1602090815260408083206001600160a01b0389811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918d917f3db9e29b45c5fe72aaa0bdc4514d68a645660185a44637e9bc6f0b805ea770459190a45b505b600585600e81111562001fe45762001fe462003444565b1480156200203957506040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200201f9190620033c3565b604051602081830303815290604052805190602001208914155b80156200205b5750600089815260d3602052604090206200205b90846200276f565b15620021f1576001600160a01b0383163b620020ba5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b6040516331a9108f60e11b81526004810183905230906001600160a01b03851690636352211e90602401602060405180830381865afa15801562002102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200212891906200345a565b6001600160a01b031614620021745760405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081d1bdad95b9259607a1b604482015260640162000690565b6200218189848462002792565b6040516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490528416906323b872dd90606401600060405180830381600087803b158015620021d257600080fd5b505af1158015620021e7573d6000803e3d6000fd5b5050505062002256565b6040516340c10f1960e01b81526001600160a01b038581166004830152602482018490528216906340c10f1990604401600060405180830381600087803b1580156200223c57600080fd5b505af115801562002251573d6000803e3d6000fd5b505050505b806001600160a01b0316836001600160a01b03168a7f2735a548eee1cda16c2df4c1a546c0376f3b3bb2ceca4966ef9d251fcbdd3c45856040516200229d91815260200190565b60405180910390a45091979650505050505050565b6000620012d5838362002840565b600062000650825490565b6040805160a08101825260056080820190815281526001600160a01b0380861660208084019190915290851682840152606080830185905292516200231391839101620035ae565b6040516020818303038152906040529150509392505050565b600084815260d360205260408120606091906200234a90866200276f565b9050806200237e576200235e86866200286d565b62002376858585620023708962002986565b62002a84565b91506200238e565b6200238b858585620022cb565b91505b846001600160a01b0316867fd0fe87fb12c7aa2b7f679256044123cb20de43059fb2ddbb4cc6556f217f29dc85604051620023cb91815260200190565b60405180910390a350949350505050565b6001600160a01b038216600090815260d260209081526040808320848452909152902054156200245e5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420746f6044820152651031b430b4b760d11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290522055565b620024908282620012dc565b62000a4c57620024ab816001600160a01b0316601462002af7565b620024b883602062002af7565b604051602001620024cb929190620035be565b60408051601f198184030181529082905262461bcd60e51b82526200069091600401620031fe565b620024ff8282620012dc565b62000a4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620025393390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012d5836001600160a01b03841662002cb0565b620025a08282620012dc565b1562000a4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012d5836001600160a01b03841662002d02565b6040805160a081018252600060808201818152825260208201819052918101829052606081019190915260056200264d848462001d37565b600e81111562002661576200266162003444565b14620026bc5760405162461bcd60e51b815260206004820152602360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736044820152623332b960e91b606482015260840162000690565b620012d582840184620036fa565b620026d462002e14565b6006620026e2848462001d37565b600e811115620026f657620026f662003444565b14620027615760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604482015272666572207769746820746f6b656e20696e666f60681b606482015260840162000690565b620012d58284018462003719565b6001600160a01b03811660009081526001830160205260408120541515620012d5565b6001600160a01b038216600090815260d2602090815260408083208484529091529020548314620028175760405162461bcd60e51b815260206004820152602860248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420667260448201526737b69031b430b4b760c11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290529081205550565b60008260000182815481106200285a576200285a620037ff565b9060005260206000200154905092915050565b6001600160a01b0381163b620028c65760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b600082815260d360205260409020620028e090826200276f565b156200292f5760405162461bcd60e51b815260206004820152601e60248201527f45524337323120546f6b656e2077617320616c72656164792061646465640000604482015260640162000690565b600082815260d3602052604090206200294990826200257d565b506040516000906001600160a01b0383169084907f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c908490a45050565b60408051808201909152606080825260208201526040518060400160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015620029e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002a0e919081019062003815565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002a52573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002a7c919081019062003815565b905292915050565b6040805160e081018252600660c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a0830186905290825260208083018590529251909262002add918391016200388b565b604051602081830303815290604052915050949350505050565b6060600062002b08836002620038fc565b62002b159060026200391e565b6001600160401b0381111562002b2f5762002b2f62002edc565b6040519080825280601f01601f19166020018201604052801562002b5a576020820181803683370190505b509050600360fc1b8160008151811062002b785762002b78620037ff565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002baa5762002baa620037ff565b60200101906001600160f81b031916908160001a905350600062002bd0846002620038fc565b62002bdd9060016200391e565b90505b600181111562002c5f576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002c155762002c15620037ff565b1a60f81b82828151811062002c2e5762002c2e620037ff565b60200101906001600160f81b031916908160001a90535060049490941c9362002c578162003934565b905062002be0565b508315620012d55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000690565b600081815260018301602052604081205462002cf95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000650565b50600062000650565b6000818152600183016020526040812054801562002dfb57600062002d296001836200394e565b855490915060009062002d3f906001906200394e565b905081811462002dab57600086600001828154811062002d635762002d63620037ff565b906000526020600020015490508087600001848154811062002d895762002d89620037ff565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002dbf5762002dbf62003964565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000650565b600091505062000650565b612a55806200397b83390190565b6040805160e081018252600060c08201818152928201928352606082018190526080820181905260a0820152908190815260200162002e66604051806040016040528060608152602001606081525090565b905290565b60006020828403121562002e7e57600080fd5b81356001600160e01b031981168114620012d557600080fd5b6001600160a01b038116811462001be257600080fd5b6000806040838503121562002ec157600080fd5b823562002ece8162002e97565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171562002f175762002f1762002edc565b60405290565b604051601f8201601f191681016001600160401b038111828210171562002f485762002f4862002edc565b604052919050565b60006001600160401b0382111562002f6c5762002f6c62002edc565b50601f01601f191660200190565b600082601f83011262002f8c57600080fd5b813562002fa362002f9d8262002f50565b62002f1d565b81815284602083860101111562002fb957600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121562002fef57600080fd5b85356001600160401b038111156200300657600080fd5b620030148882890162002f7a565b9550506020860135620030278162002e97565b93506040860135620030398162002e97565b925060608601356200304b8162002e97565b915060808601356200305d8162002e97565b809150509295509295909350565b6000602082840312156200307e57600080fd5b5035919050565b60008083601f8401126200309857600080fd5b5081356001600160401b03811115620030b057600080fd5b602083019150836020828501011115620030c957600080fd5b9250929050565b60008060008060608587031215620030e757600080fd5b84356001600160401b03811115620030fe57600080fd5b6200310c8782880162003085565b9095509350506020850135620031228162002e97565b9396929550929360400135925050565b600080604083850312156200314657600080fd5b8235915060208301356200315a8162002e97565b809150509250929050565b600080602083850312156200317957600080fd5b82356001600160401b038111156200319057600080fd5b6200319e8582860162003085565b90969095509350505050565b60005b83811015620031c7578181015183820152602001620031ad565b50506000910152565b60008151808452620031ea816020860160208601620031aa565b601f01601f19169290920160200192915050565b602081526000620012d56020830184620031d0565b600080600080606085870312156200322a57600080fd5b84356001600160401b038111156200324157600080fd5b6200324f8782880162003085565b9095509350506020850135620032658162002e97565b91506040850135620032778162002e97565b939692955090935050565b600080600080606085870312156200329957600080fd5b843593506020850135620032ad8162002e97565b925060408501356001600160401b03811115620032c957600080fd5b620032d78782880162003085565b95989497509550505050565b60008060408385031215620032f757600080fd5b50508035926020909101359150565b6000602082840312156200331957600080fd5b8135620012d58162002e97565b6000806000604084860312156200333c57600080fd5b83356001600160401b038111156200335357600080fd5b620033618682870162003085565b9094509250506020840135620033778162002e97565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251620033d7818460208701620031aa565b9190910192915050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156200343357600080fd5b81518015158114620012d557600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156200346d57600080fd5b8151620012d58162002e97565b8381526001600160a01b0383166020820152606060408201819052600090620034a690830184620031d0565b95945050505050565b600082620034cd57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115620034e357600080fd5b83861115620034f157600080fd5b5050820193919092039150565b8035600f81106200350e57600080fd5b919050565b6000602082840312156200352657600080fd5b620012d582620034fe565b604081526000620035466040830185620031d0565b8281036020840152620034a68185620031d0565b805151600f81106200357c57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b039081169184019190915260408083015190911690830152606090810151910152565b608081016200065082846200355a565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620035f8816017850160208801620031aa565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516200362b816028840160208801620031aa565b01602801949350505050565b600081830360808112156200364b57600080fd5b604051608081016001600160401b03828210818311171562003671576200367162002edc565b8160405282945060208412156200368757600080fd5b60a0830193508184108185111715620036a457620036a462002edc565b5082604052620036b485620034fe565b8152815260208401359150620036ca8262002e97565b81602082015260408401359150620036e28262002e97565b81604082015260608401356060820152505092915050565b6000608082840312156200370d57600080fd5b620012d5838362003637565b6000602082840312156200372c57600080fd5b81356001600160401b03808211156200374457600080fd5b9083019060a082860312156200375957600080fd5b6200376362002ef2565b6200376f868462003637565b81526080830135828111156200378457600080fd5b9290920191604083870312156200379a57600080fd5b620037a462002ef2565b833583811115620037b457600080fd5b620037c28882870162002f7a565b825250602084013583811115620037d857600080fd5b620037e68882870162002f7a565b6020830152508060208301525080935050505092915050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200382857600080fd5b81516001600160401b038111156200383f57600080fd5b8201601f810184136200385157600080fd5b80516200386262002f9d8262002f50565b8181528560208385010111156200387857600080fd5b620034a6826020830160208601620031aa565b602081526200389f6020820183516200355a565b6000602083015160a0808401528051604060c0850152620038c5610100850182620031d0565b90506020820151915060bf198482030160e0850152620034a68183620031d0565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620039195762003919620038e6565b500290565b80820180821115620006505762000650620038e6565b600081620039465762003946620038e6565b506000190190565b81810381811115620006505762000650620038e6565b634e487b7160e01b600052603160045260246000fdfe60806040523480156200001157600080fd5b5060405162002a5538038062002a558339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b62000a3c1760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b62000a4b1760201c565b6200013e83836200024660201b62000a741760201c565b62000153620001e860201b62000a4b1760201c565b6200016e60008051602062002a3583398151915280620002b2565b6200018960008051602062002a3583398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60c962000373838262000698565b5060ca62000382828262000698565b505050565b6200039e8282620003c560201b62000aa51760201c565b60008281526097602090815260409091206200038291839062000b2b62000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6122a180620007746000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220e9aba35f782fd339b68cf1550bc34c62e595e97e45bdf03ed99ec5022485429664736f6c63430008100033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002495760003560e01c80636d611286116200013d578063b9581c5011620000bb578063cb703bff1162000086578063cb703bff14620005a6578063cc5b715b14620005bd578063d547741f14620005e5578063dec2deb614620005fc578063edcc12b5146200061157600080fd5b8063b9581c501462000537578063c0e312dc1462000541578063ca15c8731462000558578063ca99be02146200056f57600080fd5b80639010d07c11620001085780639010d07c14620004ae57806391d1485414620004c5578063a217fddf14620004dc578063aebaaca914620004e5578063b4a0522b146200050b57600080fd5b80636d61128614620004585780636d6c68e6146200046c5780636e81ae281462000480578063884cee5a146200049757600080fd5b80632f2ff15d11620001cb5780633fa194ce11620001965780633fa194ce14620003c957806350f4428014620003e05780635573b8b61462000416578063680ae2fe146200042a5780636ce681d2146200044157600080fd5b80632f2ff15d146200037a57806336568abe146200039157806339927cf914620003a85780633b690b6b14620003bf57600080fd5b80630f1a8f7411620002185780630f1a8f7414620002da5780631e0594e3146200031f578063248a9ca3146200033657806328c5e182146200035c5780632dc151de146200036657600080fd5b806301ffc9a7146200024e578063029996b8146200027a5780630b6c672314620002865780630b885ac314620002c3575b600080fd5b620002656200025f36600462002e6b565b62000628565b60405190151581526020015b60405180910390f35b6200028462000656565b005b620002b46200029736600462002ead565b60d260209081526000928352604080842090915290825290205481565b60405190815260200162000271565b62000284620002d436600462002fd6565b620006ae565b62000306620002eb3660046200306b565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200162000271565b6200028462000330366004620030d0565b620006c4565b620002b4620003473660046200306b565b60009081526065602052604090206001015490565b620002b462000955565b60ca5462000306906001600160a01b031681565b620002846200038b36600462003132565b620009a0565b62000284620003a236600462003132565b620009ce565b62000265620003b936600462003165565b62000a50565b620002b460cc5481565b620002b4600080516020620063d083398151915281565b620004076040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002719190620031fe565b60c95462000306906001600160a01b031681565b620002846200043b36600462003213565b62000aad565b620002846200045236600462002fd6565b62000dc6565b60cd5462000306906001600160a01b031681565b60cb5462000306906001600160a01b031681565b620002846200049136600462002ead565b6200103a565b62000284620004a836600462003282565b6200114e565b62000306620004bf366004620032e3565b620012bb565b62000265620004d636600462003132565b620012dc565b620002b4600081565b62000265620004f636600462003306565b60d06020526000908152604090205460ff1681565b620003066200051c36600462003306565b60cf602052600090815260409020546001600160a01b031681565b6200028462001307565b620002846200055236600462003165565b62001350565b620002b4620005693660046200306b565b6200146e565b620003066200058036600462003132565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b62000284620005b736600462003326565b62001487565b620002b47ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000284620005f636600462003132565b6200160e565b60cd546200026590600160a01b900460ff1681565b620002846200062236600462003306565b62001637565b60006001600160e01b03198216635a05180f60e01b1480620006505750620006508262001753565b92915050565b62000671600080516020620063d083398151915233620012dc565b620006995760405162461bcd60e51b8152600401620006909062003382565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006bd858585858562000dc6565b5050505050565b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040513394509092506200071091508490602001620033c3565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000752929101620033c3565b604051602081830303815290604052805190602001208103620007d15760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606482015260840162000690565b6001600160a01b038216620008295760405162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656365697665722061646472657373000000000000604482015260640162000690565b600081815260ce60205260409020546001600160a01b03166200088f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b60008787604051602001620008a6929190620033e1565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b1580156200090a57600080fd5b505af11580156200091f573d6000803e3d6000fd5b505050600082815260ce60205260409020546200094b915082906001600160a01b03168833896200178a565b5050505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009879190620033c3565b6040516020818303038152906040528051906020012081565b600082815260656020526040902060010154620009bd8162001bd6565b620009c9838362001be5565b505050565b6001600160a01b038116331462000a405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840162000690565b62000a4c828262001c0b565b5050565b6000806001600160a01b031660ce6000858560405160200162000a75929190620033e1565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b62000ad97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012dc565b62000b275760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604482015260640162000690565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9062000b5b9087908790600401620033f1565b602060405180830381865afa15801562000b79573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b9f919062003420565b62000be65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b604482015260640162000690565b6001600160a01b0381163b62000c3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b6000848460405160200162000c56929190620033e1565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b03888116835294529190912054909250161562000cda5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b604482015260640162000690565b6001600160a01b038216600090815260d0602052604090205460ff161562000d455760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c7265616479206164646564000000000000000000604482015260640162000690565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c91a45050505050565b600054610100900460ff161580801562000de75750600054600160ff909116105b8062000e035750303b15801562000e03575060005460ff166001145b62000e685760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000690565b6000805460ff19166001179055801562000e8c576000805461ff0019166101001790555b6001600160a01b03821662000ee45760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b62000eee62001c31565b62000efb60003362001ca0565b62000f16600080516020620063d08339815191523362001ca0565b62000f427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001ca0565b8560405160200162000f559190620033c3565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562001032576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200107f929101620033c3565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620010d257600080fd5b505af1158015620010e7573d6000803e3d6000fd5b5050505062000a4c6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620011219190620033c3565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168433856200178a565b60c9546001600160a01b03163314620011aa5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604482015260640162000690565b838360cc548214158015620011c65750620011c6828262001cac565b620012145760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f72726563740000000000604482015260640162000690565b600062001222858562001d37565b90506000600682600e8111156200123d576200123d62003444565b14806200125e5750600582600e8111156200125c576200125c62003444565b145b1562001279576200127188878762001d8e565b90506200094b565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604482015260640162000690565b6000828152609760205260408120620012d59083620022b2565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b62001322600080516020620063d083398151915233620012dc565b620013415760405162461bcd60e51b8152600401620006909062003382565b60cd805460ff60a01b19169055565b60ca546001600160a01b031633148062001372575062001372600033620012dc565b620013b85760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b60008282604051602001620013cf929190620033e1565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b03166200144e5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604482015260640162000690565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206200065090620022c0565b60ca546001600160a01b0316331480620014a95750620014a9600033620012dc565b620014ef5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b6000838360405160200162001506929190620033e1565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620015865760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604482015260640162000690565b6001600160a01b038216620015de5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b6000828152606560205260409020600101546200162b8162001bd6565b620009c9838362001c0b565b62001644600033620012dc565b620016925760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604482015260640162000690565b6001600160a01b038116620016ea5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200065057506301ffc9a760e01b6001600160e01b031983161462000650565b600085815260d1602090815260408083206001600160a01b038088168552925282205416806200182757506001600160a01b038416600090815260d06020526040902054849060ff1615620018225760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b600191505b6001600160a01b0381163b620018805760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604482015260640162000690565b60405163020604bf60e21b81526004810184905230906001600160a01b0383169063081812fc90602401602060405180830381865afa158015620018c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018ee91906200345a565b6001600160a01b031614620019465760405162461bcd60e51b815260206004820152601860248201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604482015260640162000690565b600062001955868686620022cb565b9050821562001a9d576040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620019909190620033c3565b60405160208183030381529060405280519060200120880362001a125760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606482015260840162000690565b62001a20888333876200232c565b905062001a2f888386620023dc565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001a7e57600080fd5b505af115801562001a93573d6000803e3d6000fd5b5050505062001b62565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001aec57600080fd5b505af115801562001b01573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018790526001600160a01b03851692506342966c689150602401600060405180830381600087803b15801562001b4857600080fd5b505af115801562001b5d573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001b98908b908b9086906004016200347a565b600060405180830381600087803b15801562001bb357600080fd5b505af115801562001bc8573d6000803e3d6000fd5b505050505050505050505050565b62001be2813362002484565b50565b62001bf18282620024f3565b6000828152609760205260409020620009c990826200257d565b62001c17828262002594565b6000828152609760205260409020620009c99082620025fe565b600054610100900460ff1662001c9e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000690565b565b62000a4c828262001be5565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001ce09190620033c3565b60405160208183030381529060405280519060200120831462001d2057600083815260ce60205260409020546001600160a01b03838116911614620012d5565b5060cd546001600160a01b03908116911614919050565b60008062001d48838501856200306b565b905062001d57602082620034af565b60000362001d805762001d7762001d7184838188620034d2565b62001d37565b91505062000650565b62001d778385018562003513565b60008062001d9d848462001d37565b90506000808080600585600e81111562001dbb5762001dbb62003444565b0362001e1557600062001dcf898962002615565b60408082015160208084015160609094015160008f815260d183528481206001600160a01b0380881683529352939093205491985092965090945016915062001fcd9050565b600062001e238989620026ca565b905080600001516040015194508060000151602001519350806000015160600151925060d160008b81526020019081526020016000206000856001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b03160362001fcb5760cd54600160a01b900460ff1662001f085760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604482015260640162000690565b602080820151805191015160405162001f219062002e06565b62001f2e92919062003531565b604051809103906000f08015801562001f4b573d6000803e3d6000fd5b5060008b815260d1602090815260408083206001600160a01b0389811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918d917f3db9e29b45c5fe72aaa0bdc4514d68a645660185a44637e9bc6f0b805ea770459190a45b505b600585600e81111562001fe45762001fe462003444565b1480156200203957506040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200201f9190620033c3565b604051602081830303815290604052805190602001208914155b80156200205b5750600089815260d3602052604090206200205b90846200276f565b15620021f1576001600160a01b0383163b620020ba5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b6040516331a9108f60e11b81526004810183905230906001600160a01b03851690636352211e90602401602060405180830381865afa15801562002102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200212891906200345a565b6001600160a01b031614620021745760405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081d1bdad95b9259607a1b604482015260640162000690565b6200218189848462002792565b6040516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490528416906323b872dd90606401600060405180830381600087803b158015620021d257600080fd5b505af1158015620021e7573d6000803e3d6000fd5b5050505062002256565b6040516340c10f1960e01b81526001600160a01b038581166004830152602482018490528216906340c10f1990604401600060405180830381600087803b1580156200223c57600080fd5b505af115801562002251573d6000803e3d6000fd5b505050505b806001600160a01b0316836001600160a01b03168a7f2735a548eee1cda16c2df4c1a546c0376f3b3bb2ceca4966ef9d251fcbdd3c45856040516200229d91815260200190565b60405180910390a45091979650505050505050565b6000620012d5838362002840565b600062000650825490565b6040805160a08101825260056080820190815281526001600160a01b0380861660208084019190915290851682840152606080830185905292516200231391839101620035ae565b6040516020818303038152906040529150509392505050565b600084815260d360205260408120606091906200234a90866200276f565b9050806200237e576200235e86866200286d565b62002376858585620023708962002986565b62002a84565b91506200238e565b6200238b858585620022cb565b91505b846001600160a01b0316867fd0fe87fb12c7aa2b7f679256044123cb20de43059fb2ddbb4cc6556f217f29dc85604051620023cb91815260200190565b60405180910390a350949350505050565b6001600160a01b038216600090815260d260209081526040808320848452909152902054156200245e5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420746f6044820152651031b430b4b760d11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290522055565b620024908282620012dc565b62000a4c57620024ab816001600160a01b0316601462002af7565b620024b883602062002af7565b604051602001620024cb929190620035be565b60408051601f198184030181529082905262461bcd60e51b82526200069091600401620031fe565b620024ff8282620012dc565b62000a4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620025393390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012d5836001600160a01b03841662002cb0565b620025a08282620012dc565b1562000a4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012d5836001600160a01b03841662002d02565b6040805160a081018252600060808201818152825260208201819052918101829052606081019190915260056200264d848462001d37565b600e81111562002661576200266162003444565b14620026bc5760405162461bcd60e51b815260206004820152602360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736044820152623332b960e91b606482015260840162000690565b620012d582840184620036fa565b620026d462002e14565b6006620026e2848462001d37565b600e811115620026f657620026f662003444565b14620027615760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604482015272666572207769746820746f6b656e20696e666f60681b606482015260840162000690565b620012d58284018462003719565b6001600160a01b03811660009081526001830160205260408120541515620012d5565b6001600160a01b038216600090815260d2602090815260408083208484529091529020548314620028175760405162461bcd60e51b815260206004820152602860248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420667260448201526737b69031b430b4b760c11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290529081205550565b60008260000182815481106200285a576200285a620037ff565b9060005260206000200154905092915050565b6001600160a01b0381163b620028c65760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b600082815260d360205260409020620028e090826200276f565b156200292f5760405162461bcd60e51b815260206004820152601e60248201527f45524337323120546f6b656e2077617320616c72656164792061646465640000604482015260640162000690565b600082815260d3602052604090206200294990826200257d565b506040516000906001600160a01b0383169084907f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c908490a45050565b60408051808201909152606080825260208201526040518060400160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015620029e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002a0e919081019062003815565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002a52573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002a7c919081019062003815565b905292915050565b6040805160e081018252600660c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a0830186905290825260208083018590529251909262002add918391016200388b565b604051602081830303815290604052915050949350505050565b6060600062002b08836002620038fc565b62002b159060026200391e565b6001600160401b0381111562002b2f5762002b2f62002edc565b6040519080825280601f01601f19166020018201604052801562002b5a576020820181803683370190505b509050600360fc1b8160008151811062002b785762002b78620037ff565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002baa5762002baa620037ff565b60200101906001600160f81b031916908160001a905350600062002bd0846002620038fc565b62002bdd9060016200391e565b90505b600181111562002c5f576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002c155762002c15620037ff565b1a60f81b82828151811062002c2e5762002c2e620037ff565b60200101906001600160f81b031916908160001a90535060049490941c9362002c578162003934565b905062002be0565b508315620012d55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000690565b600081815260018301602052604081205462002cf95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000650565b50600062000650565b6000818152600183016020526040812054801562002dfb57600062002d296001836200394e565b855490915060009062002d3f906001906200394e565b905081811462002dab57600086600001828154811062002d635762002d63620037ff565b906000526020600020015490508087600001848154811062002d895762002d89620037ff565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002dbf5762002dbf62003964565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000650565b600091505062000650565b612a55806200397b83390190565b6040805160e081018252600060c08201818152928201928352606082018190526080820181905260a0820152908190815260200162002e66604051806040016040528060608152602001606081525090565b905290565b60006020828403121562002e7e57600080fd5b81356001600160e01b031981168114620012d557600080fd5b6001600160a01b038116811462001be257600080fd5b6000806040838503121562002ec157600080fd5b823562002ece8162002e97565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171562002f175762002f1762002edc565b60405290565b604051601f8201601f191681016001600160401b038111828210171562002f485762002f4862002edc565b604052919050565b60006001600160401b0382111562002f6c5762002f6c62002edc565b50601f01601f191660200190565b600082601f83011262002f8c57600080fd5b813562002fa362002f9d8262002f50565b62002f1d565b81815284602083860101111562002fb957600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121562002fef57600080fd5b85356001600160401b038111156200300657600080fd5b620030148882890162002f7a565b9550506020860135620030278162002e97565b93506040860135620030398162002e97565b925060608601356200304b8162002e97565b915060808601356200305d8162002e97565b809150509295509295909350565b6000602082840312156200307e57600080fd5b5035919050565b60008083601f8401126200309857600080fd5b5081356001600160401b03811115620030b057600080fd5b602083019150836020828501011115620030c957600080fd5b9250929050565b60008060008060608587031215620030e757600080fd5b84356001600160401b03811115620030fe57600080fd5b6200310c8782880162003085565b9095509350506020850135620031228162002e97565b9396929550929360400135925050565b600080604083850312156200314657600080fd5b8235915060208301356200315a8162002e97565b809150509250929050565b600080602083850312156200317957600080fd5b82356001600160401b038111156200319057600080fd5b6200319e8582860162003085565b90969095509350505050565b60005b83811015620031c7578181015183820152602001620031ad565b50506000910152565b60008151808452620031ea816020860160208601620031aa565b601f01601f19169290920160200192915050565b602081526000620012d56020830184620031d0565b600080600080606085870312156200322a57600080fd5b84356001600160401b038111156200324157600080fd5b6200324f8782880162003085565b9095509350506020850135620032658162002e97565b91506040850135620032778162002e97565b939692955090935050565b600080600080606085870312156200329957600080fd5b843593506020850135620032ad8162002e97565b925060408501356001600160401b03811115620032c957600080fd5b620032d78782880162003085565b95989497509550505050565b60008060408385031215620032f757600080fd5b50508035926020909101359150565b6000602082840312156200331957600080fd5b8135620012d58162002e97565b6000806000604084860312156200333c57600080fd5b83356001600160401b038111156200335357600080fd5b620033618682870162003085565b9094509250506020840135620033778162002e97565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251620033d7818460208701620031aa565b9190910192915050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156200343357600080fd5b81518015158114620012d557600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156200346d57600080fd5b8151620012d58162002e97565b8381526001600160a01b0383166020820152606060408201819052600090620034a690830184620031d0565b95945050505050565b600082620034cd57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115620034e357600080fd5b83861115620034f157600080fd5b5050820193919092039150565b8035600f81106200350e57600080fd5b919050565b6000602082840312156200352657600080fd5b620012d582620034fe565b604081526000620035466040830185620031d0565b8281036020840152620034a68185620031d0565b805151600f81106200357c57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b039081169184019190915260408083015190911690830152606090810151910152565b608081016200065082846200355a565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620035f8816017850160208801620031aa565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516200362b816028840160208801620031aa565b01602801949350505050565b600081830360808112156200364b57600080fd5b604051608081016001600160401b03828210818311171562003671576200367162002edc565b8160405282945060208412156200368757600080fd5b60a0830193508184108185111715620036a457620036a462002edc565b5082604052620036b485620034fe565b8152815260208401359150620036ca8262002e97565b81602082015260408401359150620036e28262002e97565b81604082015260608401356060820152505092915050565b6000608082840312156200370d57600080fd5b620012d5838362003637565b6000602082840312156200372c57600080fd5b81356001600160401b03808211156200374457600080fd5b9083019060a082860312156200375957600080fd5b6200376362002ef2565b6200376f868462003637565b81526080830135828111156200378457600080fd5b9290920191604083870312156200379a57600080fd5b620037a462002ef2565b833583811115620037b457600080fd5b620037c28882870162002f7a565b825250602084013583811115620037d857600080fd5b620037e68882870162002f7a565b6020830152508060208301525080935050505092915050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200382857600080fd5b81516001600160401b038111156200383f57600080fd5b8201601f810184136200385157600080fd5b80516200386262002f9d8262002f50565b8181528560208385010111156200387857600080fd5b620034a6826020830160208601620031aa565b602081526200389f6020820183516200355a565b6000602083015160a0808401528051604060c0850152620038c5610100850182620031d0565b90506020820151915060bf198482030160e0850152620034a68183620031d0565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620039195762003919620038e6565b500290565b80820180821115620006505762000650620038e6565b600081620039465762003946620038e6565b506000190190565b81810381811115620006505762000650620038e6565b634e487b7160e01b600052603160045260246000fdfe60806040523480156200001157600080fd5b5060405162002a5538038062002a558339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b62000a3c1760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b62000a4b1760201c565b6200013e83836200024660201b62000a741760201c565b62000153620001e860201b62000a4b1760201c565b6200016e60008051602062002a3583398151915280620002b2565b6200018960008051602062002a3583398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60c962000373838262000698565b5060ca62000382828262000698565b505050565b6200039e8282620003c560201b62000aa51760201c565b60008281526097602090815260409091206200038291839062000b2b62000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6122a180620007746000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220e9aba35f782fd339b68cf1550bc34c62e595e97e45bdf03ed99ec5022485429664736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.meta.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.meta.json new file mode 100644 index 000000000..cd50dd2e7 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721.meta.json @@ -0,0 +1,410 @@ +{ + "name": "TokenManagerERC721", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721WithMetadata.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721WithMetadata.json new file mode 100644 index 000000000..f6f32e5c8 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721WithMetadata.json @@ -0,0 +1,861 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerERC721WithMetadata", + "sourceName": "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldValue", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "DepositBoxWasChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "ERC721TokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "ERC721TokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721TokenReady", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "chainHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ERC721TokenReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetChainName", + "type": "string" + }, + { + "internalType": "address", + "name": "erc721OnMainChain", + "type": "address" + }, + { + "internalType": "address", + "name": "erc721OnSchain", + "type": "address" + } + ], + "name": "addERC721TokenByOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC721OnChain", + "name": "", + "type": "address" + } + ], + "name": "addedClones", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "clonesErc721", + "outputs": [ + { + "internalType": "contract ERC721OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract ICommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deprecatedClonesErc721", + "outputs": [ + { + "internalType": "contract ERC721OnChain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "exitToMainERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract ITokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "targetSchainName", + "type": "string" + }, + { + "internalType": "address", + "name": "contractOnMainnet", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferToSchainERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transferredAmount", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b506166ba806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620002495760003560e01c80636d611286116200013d578063b9581c5011620000bb578063cb703bff1162000086578063cb703bff14620005a6578063cc5b715b14620005bd578063d547741f14620005e5578063dec2deb614620005fc578063edcc12b5146200061157600080fd5b8063b9581c501462000537578063c0e312dc1462000541578063ca15c8731462000558578063ca99be02146200056f57600080fd5b80639010d07c11620001085780639010d07c14620004ae57806391d1485414620004c5578063a217fddf14620004dc578063aebaaca914620004e5578063b4a0522b146200050b57600080fd5b80636d61128614620004585780636d6c68e6146200046c5780636e81ae281462000480578063884cee5a146200049757600080fd5b80632f2ff15d11620001cb5780633fa194ce11620001965780633fa194ce14620003c957806350f4428014620003e05780635573b8b61462000416578063680ae2fe146200042a5780636ce681d2146200044157600080fd5b80632f2ff15d146200037a57806336568abe146200039157806339927cf914620003a85780633b690b6b14620003bf57600080fd5b80630f1a8f7411620002185780630f1a8f7414620002da5780631e0594e3146200031f578063248a9ca3146200033657806328c5e182146200035c5780632dc151de146200036657600080fd5b806301ffc9a7146200024e578063029996b8146200027a5780630b6c672314620002865780630b885ac314620002c3575b600080fd5b620002656200025f36600462003020565b62000628565b60405190151581526020015b60405180910390f35b6200028462000656565b005b620002b46200029736600462003062565b60d260209081526000928352604080842090915290825290205481565b60405190815260200162000271565b62000284620002d4366004620031d5565b620006ae565b62000306620002eb3660046200326a565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200162000271565b6200028462000330366004620032cf565b620006c4565b620002b4620003473660046200326a565b60009081526065602052604090206001015490565b620002b462000955565b60ca5462000306906001600160a01b031681565b620002846200038b36600462003331565b620009a0565b62000284620003a236600462003331565b620009ce565b62000265620003b936600462003364565b62000a50565b620002b460cc5481565b620002b46000805160206200666583398151915281565b620004076040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002719190620033fd565b60c95462000306906001600160a01b031681565b620002846200043b36600462003412565b62000aad565b6200028462000452366004620031d5565b62000dc6565b60cd5462000306906001600160a01b031681565b60cb5462000306906001600160a01b031681565b620002846200049136600462003062565b6200103a565b62000284620004a836600462003481565b6200114e565b62000306620004bf366004620034e2565b620012bb565b62000265620004d636600462003331565b620012dc565b620002b4600081565b62000265620004f636600462003505565b60d06020526000908152604090205460ff1681565b620003066200051c36600462003505565b60cf602052600090815260409020546001600160a01b031681565b6200028462001307565b620002846200055236600462003364565b62001350565b620002b4620005693660046200326a565b6200146e565b620003066200058036600462003331565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b62000284620005b736600462003525565b62001487565b620002b47ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000284620005f636600462003331565b6200160e565b60cd546200026590600160a01b900460ff1681565b620002846200062236600462003505565b62001637565b60006001600160e01b03198216635a05180f60e01b1480620006505750620006508262001753565b92915050565b620006716000805160206200666583398151915233620012dc565b620006995760405162461bcd60e51b8152600401620006909062003581565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006bd858585858562000dc6565b5050505050565b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040513394509092506200071091508490602001620035c2565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000752929101620035c2565b604051602081830303815290604052805190602001208103620007d15760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606482015260840162000690565b6001600160a01b038216620008295760405162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656365697665722061646472657373000000000000604482015260640162000690565b600081815260ce60205260409020546001600160a01b03166200088f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b60008787604051602001620008a6929190620035e0565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b1580156200090a57600080fd5b505af11580156200091f573d6000803e3d6000fd5b505050600082815260ce60205260409020546200094b915082906001600160a01b03168833896200178a565b5050505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009879190620035c2565b6040516020818303038152906040528051906020012081565b600082815260656020526040902060010154620009bd8162001be2565b620009c9838362001bf1565b505050565b6001600160a01b038116331462000a405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840162000690565b62000a4c828262001c17565b5050565b6000806001600160a01b031660ce6000858560405160200162000a75929190620035e0565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b62000ad97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012dc565b62000b275760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604482015260640162000690565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9062000b5b9087908790600401620035f0565b602060405180830381865afa15801562000b79573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b9f91906200361f565b62000be65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b604482015260640162000690565b6001600160a01b0381163b62000c3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b6000848460405160200162000c56929190620035e0565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b03888116835294529190912054909250161562000cda5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b604482015260640162000690565b6001600160a01b038216600090815260d0602052604090205460ff161562000d455760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c7265616479206164646564000000000000000000604482015260640162000690565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c91a45050505050565b600054610100900460ff161580801562000de75750600054600160ff909116105b8062000e035750303b15801562000e03575060005460ff166001145b62000e685760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000690565b6000805460ff19166001179055801562000e8c576000805461ff0019166101001790555b6001600160a01b03821662000ee45760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b62000eee62001c3d565b62000efb60003362001cac565b62000f16600080516020620066658339815191523362001cac565b62000f427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001cac565b8560405160200162000f559190620035c2565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562001032576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200107f929101620035c2565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620010d257600080fd5b505af1158015620010e7573d6000803e3d6000fd5b5050505062000a4c6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620011219190620035c2565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168433856200178a565b60c9546001600160a01b03163314620011aa5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604482015260640162000690565b838360cc548214158015620011c65750620011c6828262001cb8565b620012145760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f72726563740000000000604482015260640162000690565b600062001222858562001d43565b90506000600e82600e8111156200123d576200123d62003643565b14806200125e5750600d82600e8111156200125c576200125c62003643565b145b1562001279576200127188878762001d9a565b90506200094b565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604482015260640162000690565b6000828152609760205260408120620012d5908362002378565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b620013226000805160206200666583398151915233620012dc565b620013415760405162461bcd60e51b8152600401620006909062003581565b60cd805460ff60a01b19169055565b60ca546001600160a01b031633148062001372575062001372600033620012dc565b620013b85760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b60008282604051602001620013cf929190620035e0565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b03166200144e5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604482015260640162000690565b600090815260ce6020526040902080546001600160a01b03191690555050565b6000818152609760205260408120620006509062002386565b60ca546001600160a01b0316331480620014a95750620014a9600033620012dc565b620014ef5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b6000838360405160200162001506929190620035e0565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620015865760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604482015260640162000690565b6001600160a01b038216620015de5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b6000828152606560205260409020600101546200162b8162001be2565b620009c9838362001c17565b62001644600033620012dc565b620016925760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604482015260640162000690565b6001600160a01b038116620016ea5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200065057506301ffc9a760e01b6001600160e01b031983161462000650565b600085815260d1602090815260408083206001600160a01b038088168552925282205416806200182757506001600160a01b038416600090815260d06020526040902054849060ff1615620018225760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b600191505b6001600160a01b0381163b620018805760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604482015260640162000690565b60405163020604bf60e21b81526004810184905230906001600160a01b0383169063081812fc90602401602060405180830381865afa158015620018c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018ee919062003659565b6001600160a01b031614620019465760405162461bcd60e51b815260206004820152601860248201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604482015260640162000690565b6000620019618686866200195b868962002391565b62002404565b9050821562001aa9576040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200199c9190620035c2565b60405160208183030381529060405280519060200120880362001a1e5760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606482015260840162000690565b62001a2c8883338762002477565b905062001a3b8883866200252b565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001a8a57600080fd5b505af115801562001a9f573d6000803e3d6000fd5b5050505062001b6e565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001af857600080fd5b505af115801562001b0d573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018790526001600160a01b03851692506342966c689150602401600060405180830381600087803b15801562001b5457600080fd5b505af115801562001b69573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001ba4908b908b90869060040162003679565b600060405180830381600087803b15801562001bbf57600080fd5b505af115801562001bd4573d6000803e3d6000fd5b505050505050505050505050565b62001bee8133620025d3565b50565b62001bfd828262002642565b6000828152609760205260409020620009c99082620026cc565b62001c238282620026e3565b6000828152609760205260409020620009c990826200274d565b600054610100900460ff1662001caa5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000690565b565b62000a4c828262001bf1565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001cec9190620035c2565b60405160208183030381529060405280519060200120831462001d2c57600083815260ce60205260409020546001600160a01b03838116911614620012d5565b5060cd546001600160a01b03908116911614919050565b60008062001d54838501856200326a565b905062001d63602082620036ae565b60000362001d8c5762001d8362001d7d84838188620036d1565b62001d43565b91505062000650565b62001d838385018562003712565b60008062001da9848462001d43565b905060008080606081600d86600e81111562001dc95762001dc962003643565b0362001e5a57600062001ddd8a8a62002764565b90508060000151604001519550806000015160200151945080600001516060015193508060200151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002029565b600062001e688a8a6200282f565b9050806000015160000151604001519550806000015160000151602001519450806000015160000151606001519350806000015160200151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b031603620020275760cd54600160a01b900460ff1662001f645760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604482015260640162000690565b602080820151805191015160405162001f7d9062002fa9565b62001f8a92919062003730565b604051809103906000f08015801562001fa7573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918e917f3db9e29b45c5fe72aaa0bdc4514d68a645660185a44637e9bc6f0b805ea770459190a45b505b600d86600e81111562002040576200204062003643565b1480156200209557506040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200207b9190620035c2565b604051602081830303815290604052805190602001208a14155b8015620020a95750620020a98a85620028d4565b156200223f576001600160a01b0384163b620021085760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b6040516331a9108f60e11b81526004810184905230906001600160a01b03861690636352211e90602401602060405180830381865afa15801562002150573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002176919062003659565b6001600160a01b031614620021c25760405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081d1bdad95b9259607a1b604482015260640162000690565b620021cf8a85856200290b565b6040516323b872dd60e01b81523060048201526001600160a01b038681166024830152604482018590528516906323b872dd90606401600060405180830381600087803b1580156200222057600080fd5b505af115801562002235573d6000803e3d6000fd5b505050506200231b565b6040516340c10f1960e01b81526001600160a01b038681166004830152602482018590528216906340c10f1990604401600060405180830381600087803b1580156200228a57600080fd5b505af11580156200229f573d6000803e3d6000fd5b5050604051630588253160e21b81526001600160a01b038416925063162094c49150620022d3908690869060040162003759565b6020604051808303816000875af1158015620022f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200231991906200361f565b505b806001600160a01b0316846001600160a01b03168b7f2735a548eee1cda16c2df4c1a546c0376f3b3bb2ceca4966ef9d251fcbdd3c45866040516200236291815260200190565b60405180910390a4509298975050505050505050565b6000620012d58383620029b9565b600062000650825490565b60405163c87b56dd60e01b8152600481018290526060906001600160a01b0384169063c87b56dd90602401600060405180830381865afa158015620023da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620012d591908101906200377c565b6040805160e081018252600d60c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a083018690529082526020808301859052925190926200245d9183910162003863565b604051602081830303815290604052915050949350505050565b60606000620024878686620028d4565b905080620024c7576200249b8686620029e6565b620024bf858585620024ae898862002391565b620024b98a62002b1c565b62002c1a565b9150620024dd565b620024da8585856200195b898862002391565b91505b846001600160a01b0316867fd0fe87fb12c7aa2b7f679256044123cb20de43059fb2ddbb4cc6556f217f29dc856040516200251a91815260200190565b60405180910390a350949350505050565b6001600160a01b038216600090815260d26020908152604080832084845290915290205415620025ad5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420746f6044820152651031b430b4b760d11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290522055565b620025df8282620012dc565b62000a4c57620025fa816001600160a01b0316601462002c9a565b6200260783602062002c9a565b6040516020016200261a92919062003878565b60408051601f198184030181529082905262461bcd60e51b82526200069091600401620033fd565b6200264e8282620012dc565b62000a4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620026883390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012d5836001600160a01b03841662002e53565b620026ef8282620012dc565b1562000a4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012d5836001600160a01b03841662002ea5565b620027a46040805160e081018252600060c08201818152928201928352606082018190526080820181905260a08201529081908152602001606081525090565b600d620027b2848462001d43565b600e811115620027c657620027c662003643565b14620028215760405162461bcd60e51b815260206004820152602360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736044820152623332b960e91b606482015260840162000690565b620012d582840184620039c7565b6200283962002fb7565b600e62002847848462001d43565b600e8111156200285b576200285b62003643565b14620028c65760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604482015272666572207769746820746f6b656e20696e666f60681b606482015260840162000690565b620012d582840184620039ff565b600082815260d360205260408120620012d590836001600160a01b03811660009081526001830160205260408120541515620012d5565b6001600160a01b038216600090815260d2602090815260408083208484529091529020548314620029905760405162461bcd60e51b815260206004820152602860248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420667260448201526737b69031b430b4b760c11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290529081205550565b6000826000018281548110620029d357620029d362003af8565b9060005260206000200154905092915050565b6001600160a01b0381163b62002a3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b600082815260d36020526040902062002a7690826001600160a01b03811660009081526001830160205260408120541515620012d5565b1562002ac55760405162461bcd60e51b815260206004820152601e60248201527f45524337323120546f6b656e2077617320616c72656164792061646465640000604482015260640162000690565b600082815260d36020526040902062002adf9082620026cc565b506040516000906001600160a01b0383169084907f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c908490a45050565b60408051808201909152606080825260208201526040518060400160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002b7a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002ba491908101906200377c565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002be8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c1291908101906200377c565b905292915050565b6040805161012081018252600e6101008201908152608082019081526001600160a01b0380891660a0840152871660c083015260e08201869052818301908152606080830186905290825260208083018590529251909262002c7f9183910162003b0e565b60405160208183030381529060405291505095945050505050565b6060600062002cab83600262003b91565b62002cb890600262003bb3565b6001600160401b0381111562002cd25762002cd262003091565b6040519080825280601f01601f19166020018201604052801562002cfd576020820181803683370190505b509050600360fc1b8160008151811062002d1b5762002d1b62003af8565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002d4d5762002d4d62003af8565b60200101906001600160f81b031916908160001a905350600062002d7384600262003b91565b62002d8090600162003bb3565b90505b600181111562002e02576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002db85762002db862003af8565b1a60f81b82828151811062002dd15762002dd162003af8565b60200101906001600160f81b031916908160001a90535060049490941c9362002dfa8162003bc9565b905062002d83565b508315620012d55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000690565b600081815260018301602052604081205462002e9c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000650565b50600062000650565b6000818152600183016020526040812054801562002f9e57600062002ecc60018362003be3565b855490915060009062002ee29060019062003be3565b905081811462002f4e57600086600001828154811062002f065762002f0662003af8565b906000526020600020015490508087600001848154811062002f2c5762002f2c62003af8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002f625762002f6262003bf9565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000650565b600091505062000650565b612a558062003c1083390190565b6040805161012081018252600061010082018181526080830190815260a0830182905260c0830182905260e083019190915291810191825260608082015290819081526020016200301b604051806040016040528060608152602001606081525090565b905290565b6000602082840312156200303357600080fd5b81356001600160e01b031981168114620012d557600080fd5b6001600160a01b038116811462001bee57600080fd5b600080604083850312156200307657600080fd5b823562003083816200304c565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620030cc57620030cc62003091565b60405290565b604051608081016001600160401b0381118282101715620030cc57620030cc62003091565b604051602081016001600160401b0381118282101715620030cc57620030cc62003091565b604051601f8201601f191681016001600160401b038111828210171562003147576200314762003091565b604052919050565b60006001600160401b038211156200316b576200316b62003091565b50601f01601f191660200190565b600082601f8301126200318b57600080fd5b8135620031a26200319c826200314f565b6200311c565b818152846020838601011115620031b857600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215620031ee57600080fd5b85356001600160401b038111156200320557600080fd5b620032138882890162003179565b955050602086013562003226816200304c565b9350604086013562003238816200304c565b925060608601356200324a816200304c565b915060808601356200325c816200304c565b809150509295509295909350565b6000602082840312156200327d57600080fd5b5035919050565b60008083601f8401126200329757600080fd5b5081356001600160401b03811115620032af57600080fd5b602083019150836020828501011115620032c857600080fd5b9250929050565b60008060008060608587031215620032e657600080fd5b84356001600160401b03811115620032fd57600080fd5b6200330b8782880162003284565b909550935050602085013562003321816200304c565b9396929550929360400135925050565b600080604083850312156200334557600080fd5b82359150602083013562003359816200304c565b809150509250929050565b600080602083850312156200337857600080fd5b82356001600160401b038111156200338f57600080fd5b6200339d8582860162003284565b90969095509350505050565b60005b83811015620033c6578181015183820152602001620033ac565b50506000910152565b60008151808452620033e9816020860160208601620033a9565b601f01601f19169290920160200192915050565b602081526000620012d56020830184620033cf565b600080600080606085870312156200342957600080fd5b84356001600160401b038111156200344057600080fd5b6200344e8782880162003284565b909550935050602085013562003464816200304c565b9150604085013562003476816200304c565b939692955090935050565b600080600080606085870312156200349857600080fd5b843593506020850135620034ac816200304c565b925060408501356001600160401b03811115620034c857600080fd5b620034d68782880162003284565b95989497509550505050565b60008060408385031215620034f657600080fd5b50508035926020909101359150565b6000602082840312156200351857600080fd5b8135620012d5816200304c565b6000806000604084860312156200353b57600080fd5b83356001600160401b038111156200355257600080fd5b620035608682870162003284565b909450925050602084013562003576816200304c565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251620035d6818460208701620033a9565b9190910192915050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156200363257600080fd5b81518015158114620012d557600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156200366c57600080fd5b8151620012d5816200304c565b8381526001600160a01b0383166020820152606060408201819052600090620036a590830184620033cf565b95945050505050565b600082620036cc57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115620036e257600080fd5b83861115620036f057600080fd5b5050820193919092039150565b8035600f81106200370d57600080fd5b919050565b6000602082840312156200372557600080fd5b620012d582620036fd565b604081526000620037456040830185620033cf565b8281036020840152620036a58185620033cf565b828152604060208201526000620037746040830184620033cf565b949350505050565b6000602082840312156200378f57600080fd5b81516001600160401b03811115620037a657600080fd5b8201601f81018413620037b857600080fd5b8051620037c96200319c826200314f565b818152856020838501011115620037df57600080fd5b620036a5826020830160208601620033a9565b60008151805151600f81106200381857634e487b7160e01b600052602160045260246000fd5b84526020818101516001600160a01b0390811682870152604080840151909116908601526060918201519185019190915282015160a0608085018190526200377490850182620033cf565b602081526000620012d56020830184620037f2565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620038b2816017850160208801620033a9565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351620038e5816028840160208801620033a9565b01602801949350505050565b600081830360a08112156200390557600080fd5b6200390f620030a7565b915060808112156200392057600080fd5b6200392a620030d2565b60208212156200393957600080fd5b62003943620030f7565b91506200395084620036fd565b825290815260208301359062003966826200304c565b816020820152604084013591506200397e826200304c565b81604082015260608401356060820152808352505060808201356001600160401b03811115620039ad57600080fd5b620039bb8482850162003179565b60208301525092915050565b600060208284031215620039da57600080fd5b81356001600160401b03811115620039f157600080fd5b6200377484828501620038f1565b60006020828403121562003a1257600080fd5b81356001600160401b038082111562003a2a57600080fd5b908301906040828603121562003a3f57600080fd5b62003a49620030a7565b82358281111562003a5957600080fd5b62003a6787828601620038f1565b82525060208301358281111562003a7d57600080fd5b92909201916040838703121562003a9357600080fd5b62003a9d620030a7565b83358381111562003aad57600080fd5b62003abb8882870162003179565b82525060208401358381111562003ad157600080fd5b62003adf8882870162003179565b6020830152508060208301525080935050505092915050565b634e487b7160e01b600052603260045260246000fd5b60208152600082516040602084015262003b2c6060840182620037f2565b90506020840151601f1984830301604085015280516040835262003b546040840182620033cf565b905060208201519150828103602084015262003b718183620033cf565b9695505050505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161562003bae5762003bae62003b7b565b500290565b8082018082111562000650576200065062003b7b565b60008162003bdb5762003bdb62003b7b565b506000190190565b8181038181111562000650576200065062003b7b565b634e487b7160e01b600052603160045260246000fdfe60806040523480156200001157600080fd5b5060405162002a5538038062002a558339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b62000a3c1760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b62000a4b1760201c565b6200013e83836200024660201b62000a741760201c565b62000153620001e860201b62000a4b1760201c565b6200016e60008051602062002a3583398151915280620002b2565b6200018960008051602062002a3583398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60c962000373838262000698565b5060ca62000382828262000698565b505050565b6200039e8282620003c560201b62000aa51760201c565b60008281526097602090815260409091206200038291839062000b2b62000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6122a180620007746000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220f4b1a553d0216fad85e7fc3c0111d94167f74f5dbb1455424ba58f7cf0009cba64736f6c63430008100033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002495760003560e01c80636d611286116200013d578063b9581c5011620000bb578063cb703bff1162000086578063cb703bff14620005a6578063cc5b715b14620005bd578063d547741f14620005e5578063dec2deb614620005fc578063edcc12b5146200061157600080fd5b8063b9581c501462000537578063c0e312dc1462000541578063ca15c8731462000558578063ca99be02146200056f57600080fd5b80639010d07c11620001085780639010d07c14620004ae57806391d1485414620004c5578063a217fddf14620004dc578063aebaaca914620004e5578063b4a0522b146200050b57600080fd5b80636d61128614620004585780636d6c68e6146200046c5780636e81ae281462000480578063884cee5a146200049757600080fd5b80632f2ff15d11620001cb5780633fa194ce11620001965780633fa194ce14620003c957806350f4428014620003e05780635573b8b61462000416578063680ae2fe146200042a5780636ce681d2146200044157600080fd5b80632f2ff15d146200037a57806336568abe146200039157806339927cf914620003a85780633b690b6b14620003bf57600080fd5b80630f1a8f7411620002185780630f1a8f7414620002da5780631e0594e3146200031f578063248a9ca3146200033657806328c5e182146200035c5780632dc151de146200036657600080fd5b806301ffc9a7146200024e578063029996b8146200027a5780630b6c672314620002865780630b885ac314620002c3575b600080fd5b620002656200025f36600462003020565b62000628565b60405190151581526020015b60405180910390f35b6200028462000656565b005b620002b46200029736600462003062565b60d260209081526000928352604080842090915290825290205481565b60405190815260200162000271565b62000284620002d4366004620031d5565b620006ae565b62000306620002eb3660046200326a565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200162000271565b6200028462000330366004620032cf565b620006c4565b620002b4620003473660046200326a565b60009081526065602052604090206001015490565b620002b462000955565b60ca5462000306906001600160a01b031681565b620002846200038b36600462003331565b620009a0565b62000284620003a236600462003331565b620009ce565b62000265620003b936600462003364565b62000a50565b620002b460cc5481565b620002b46000805160206200666583398151915281565b620004076040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002719190620033fd565b60c95462000306906001600160a01b031681565b620002846200043b36600462003412565b62000aad565b6200028462000452366004620031d5565b62000dc6565b60cd5462000306906001600160a01b031681565b60cb5462000306906001600160a01b031681565b620002846200049136600462003062565b6200103a565b62000284620004a836600462003481565b6200114e565b62000306620004bf366004620034e2565b620012bb565b62000265620004d636600462003331565b620012dc565b620002b4600081565b62000265620004f636600462003505565b60d06020526000908152604090205460ff1681565b620003066200051c36600462003505565b60cf602052600090815260409020546001600160a01b031681565b6200028462001307565b620002846200055236600462003364565b62001350565b620002b4620005693660046200326a565b6200146e565b620003066200058036600462003331565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b62000284620005b736600462003525565b62001487565b620002b47ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000284620005f636600462003331565b6200160e565b60cd546200026590600160a01b900460ff1681565b620002846200062236600462003505565b62001637565b60006001600160e01b03198216635a05180f60e01b1480620006505750620006508262001753565b92915050565b620006716000805160206200666583398151915233620012dc565b620006995760405162461bcd60e51b8152600401620006909062003581565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006bd858585858562000dc6565b5050505050565b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040513394509092506200071091508490602001620035c2565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000752929101620035c2565b604051602081830303815290604052805190602001208103620007d15760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606482015260840162000690565b6001600160a01b038216620008295760405162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656365697665722061646472657373000000000000604482015260640162000690565b600081815260ce60205260409020546001600160a01b03166200088f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b60008787604051602001620008a6929190620035e0565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b1580156200090a57600080fd5b505af11580156200091f573d6000803e3d6000fd5b505050600082815260ce60205260409020546200094b915082906001600160a01b03168833896200178a565b5050505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009879190620035c2565b6040516020818303038152906040528051906020012081565b600082815260656020526040902060010154620009bd8162001be2565b620009c9838362001bf1565b505050565b6001600160a01b038116331462000a405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840162000690565b62000a4c828262001c17565b5050565b6000806001600160a01b031660ce6000858560405160200162000a75929190620035e0565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b62000ad97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012dc565b62000b275760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604482015260640162000690565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9062000b5b9087908790600401620035f0565b602060405180830381865afa15801562000b79573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b9f91906200361f565b62000be65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b604482015260640162000690565b6001600160a01b0381163b62000c3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b6000848460405160200162000c56929190620035e0565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b03888116835294529190912054909250161562000cda5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b604482015260640162000690565b6001600160a01b038216600090815260d0602052604090205460ff161562000d455760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c7265616479206164646564000000000000000000604482015260640162000690565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c91a45050505050565b600054610100900460ff161580801562000de75750600054600160ff909116105b8062000e035750303b15801562000e03575060005460ff166001145b62000e685760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000690565b6000805460ff19166001179055801562000e8c576000805461ff0019166101001790555b6001600160a01b03821662000ee45760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b62000eee62001c3d565b62000efb60003362001cac565b62000f16600080516020620066658339815191523362001cac565b62000f427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001cac565b8560405160200162000f559190620035c2565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562001032576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200107f929101620035c2565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620010d257600080fd5b505af1158015620010e7573d6000803e3d6000fd5b5050505062000a4c6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620011219190620035c2565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168433856200178a565b60c9546001600160a01b03163314620011aa5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604482015260640162000690565b838360cc548214158015620011c65750620011c6828262001cb8565b620012145760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f72726563740000000000604482015260640162000690565b600062001222858562001d43565b90506000600e82600e8111156200123d576200123d62003643565b14806200125e5750600d82600e8111156200125c576200125c62003643565b145b1562001279576200127188878762001d9a565b90506200094b565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604482015260640162000690565b6000828152609760205260408120620012d5908362002378565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b620013226000805160206200666583398151915233620012dc565b620013415760405162461bcd60e51b8152600401620006909062003581565b60cd805460ff60a01b19169055565b60ca546001600160a01b031633148062001372575062001372600033620012dc565b620013b85760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b60008282604051602001620013cf929190620035e0565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b03166200144e5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604482015260640162000690565b600090815260ce6020526040902080546001600160a01b03191690555050565b6000818152609760205260408120620006509062002386565b60ca546001600160a01b0316331480620014a95750620014a9600033620012dc565b620014ef5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b6000838360405160200162001506929190620035e0565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620015865760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604482015260640162000690565b6001600160a01b038216620015de5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b6000828152606560205260409020600101546200162b8162001be2565b620009c9838362001c17565b62001644600033620012dc565b620016925760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604482015260640162000690565b6001600160a01b038116620016ea5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200065057506301ffc9a760e01b6001600160e01b031983161462000650565b600085815260d1602090815260408083206001600160a01b038088168552925282205416806200182757506001600160a01b038416600090815260d06020526040902054849060ff1615620018225760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b600191505b6001600160a01b0381163b620018805760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604482015260640162000690565b60405163020604bf60e21b81526004810184905230906001600160a01b0383169063081812fc90602401602060405180830381865afa158015620018c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018ee919062003659565b6001600160a01b031614620019465760405162461bcd60e51b815260206004820152601860248201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604482015260640162000690565b6000620019618686866200195b868962002391565b62002404565b9050821562001aa9576040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200199c9190620035c2565b60405160208183030381529060405280519060200120880362001a1e5760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606482015260840162000690565b62001a2c8883338762002477565b905062001a3b8883866200252b565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001a8a57600080fd5b505af115801562001a9f573d6000803e3d6000fd5b5050505062001b6e565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001af857600080fd5b505af115801562001b0d573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018790526001600160a01b03851692506342966c689150602401600060405180830381600087803b15801562001b5457600080fd5b505af115801562001b69573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001ba4908b908b90869060040162003679565b600060405180830381600087803b15801562001bbf57600080fd5b505af115801562001bd4573d6000803e3d6000fd5b505050505050505050505050565b62001bee8133620025d3565b50565b62001bfd828262002642565b6000828152609760205260409020620009c99082620026cc565b62001c238282620026e3565b6000828152609760205260409020620009c990826200274d565b600054610100900460ff1662001caa5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000690565b565b62000a4c828262001bf1565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001cec9190620035c2565b60405160208183030381529060405280519060200120831462001d2c57600083815260ce60205260409020546001600160a01b03838116911614620012d5565b5060cd546001600160a01b03908116911614919050565b60008062001d54838501856200326a565b905062001d63602082620036ae565b60000362001d8c5762001d8362001d7d84838188620036d1565b62001d43565b91505062000650565b62001d838385018562003712565b60008062001da9848462001d43565b905060008080606081600d86600e81111562001dc95762001dc962003643565b0362001e5a57600062001ddd8a8a62002764565b90508060000151604001519550806000015160200151945080600001516060015193508060200151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002029565b600062001e688a8a6200282f565b9050806000015160000151604001519550806000015160000151602001519450806000015160000151606001519350806000015160200151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b031603620020275760cd54600160a01b900460ff1662001f645760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604482015260640162000690565b602080820151805191015160405162001f7d9062002fa9565b62001f8a92919062003730565b604051809103906000f08015801562001fa7573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918e917f3db9e29b45c5fe72aaa0bdc4514d68a645660185a44637e9bc6f0b805ea770459190a45b505b600d86600e81111562002040576200204062003643565b1480156200209557506040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200207b9190620035c2565b604051602081830303815290604052805190602001208a14155b8015620020a95750620020a98a85620028d4565b156200223f576001600160a01b0384163b620021085760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b6040516331a9108f60e11b81526004810184905230906001600160a01b03861690636352211e90602401602060405180830381865afa15801562002150573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002176919062003659565b6001600160a01b031614620021c25760405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081d1bdad95b9259607a1b604482015260640162000690565b620021cf8a85856200290b565b6040516323b872dd60e01b81523060048201526001600160a01b038681166024830152604482018590528516906323b872dd90606401600060405180830381600087803b1580156200222057600080fd5b505af115801562002235573d6000803e3d6000fd5b505050506200231b565b6040516340c10f1960e01b81526001600160a01b038681166004830152602482018590528216906340c10f1990604401600060405180830381600087803b1580156200228a57600080fd5b505af11580156200229f573d6000803e3d6000fd5b5050604051630588253160e21b81526001600160a01b038416925063162094c49150620022d3908690869060040162003759565b6020604051808303816000875af1158015620022f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200231991906200361f565b505b806001600160a01b0316846001600160a01b03168b7f2735a548eee1cda16c2df4c1a546c0376f3b3bb2ceca4966ef9d251fcbdd3c45866040516200236291815260200190565b60405180910390a4509298975050505050505050565b6000620012d58383620029b9565b600062000650825490565b60405163c87b56dd60e01b8152600481018290526060906001600160a01b0384169063c87b56dd90602401600060405180830381865afa158015620023da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620012d591908101906200377c565b6040805160e081018252600d60c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a083018690529082526020808301859052925190926200245d9183910162003863565b604051602081830303815290604052915050949350505050565b60606000620024878686620028d4565b905080620024c7576200249b8686620029e6565b620024bf858585620024ae898862002391565b620024b98a62002b1c565b62002c1a565b9150620024dd565b620024da8585856200195b898862002391565b91505b846001600160a01b0316867fd0fe87fb12c7aa2b7f679256044123cb20de43059fb2ddbb4cc6556f217f29dc856040516200251a91815260200190565b60405180910390a350949350505050565b6001600160a01b038216600090815260d26020908152604080832084845290915290205415620025ad5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420746f6044820152651031b430b4b760d11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290522055565b620025df8282620012dc565b62000a4c57620025fa816001600160a01b0316601462002c9a565b6200260783602062002c9a565b6040516020016200261a92919062003878565b60408051601f198184030181529082905262461bcd60e51b82526200069091600401620033fd565b6200264e8282620012dc565b62000a4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620026883390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012d5836001600160a01b03841662002e53565b620026ef8282620012dc565b1562000a4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012d5836001600160a01b03841662002ea5565b620027a46040805160e081018252600060c08201818152928201928352606082018190526080820181905260a08201529081908152602001606081525090565b600d620027b2848462001d43565b600e811115620027c657620027c662003643565b14620028215760405162461bcd60e51b815260206004820152602360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736044820152623332b960e91b606482015260840162000690565b620012d582840184620039c7565b6200283962002fb7565b600e62002847848462001d43565b600e8111156200285b576200285b62003643565b14620028c65760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604482015272666572207769746820746f6b656e20696e666f60681b606482015260840162000690565b620012d582840184620039ff565b600082815260d360205260408120620012d590836001600160a01b03811660009081526001830160205260408120541515620012d5565b6001600160a01b038216600090815260d2602090815260408083208484529091529020548314620029905760405162461bcd60e51b815260206004820152602860248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420667260448201526737b69031b430b4b760c11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290529081205550565b6000826000018281548110620029d357620029d362003af8565b9060005260206000200154905092915050565b6001600160a01b0381163b62002a3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b600082815260d36020526040902062002a7690826001600160a01b03811660009081526001830160205260408120541515620012d5565b1562002ac55760405162461bcd60e51b815260206004820152601e60248201527f45524337323120546f6b656e2077617320616c72656164792061646465640000604482015260640162000690565b600082815260d36020526040902062002adf9082620026cc565b506040516000906001600160a01b0383169084907f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c908490a45050565b60408051808201909152606080825260208201526040518060400160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002b7a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002ba491908101906200377c565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002be8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c1291908101906200377c565b905292915050565b6040805161012081018252600e6101008201908152608082019081526001600160a01b0380891660a0840152871660c083015260e08201869052818301908152606080830186905290825260208083018590529251909262002c7f9183910162003b0e565b60405160208183030381529060405291505095945050505050565b6060600062002cab83600262003b91565b62002cb890600262003bb3565b6001600160401b0381111562002cd25762002cd262003091565b6040519080825280601f01601f19166020018201604052801562002cfd576020820181803683370190505b509050600360fc1b8160008151811062002d1b5762002d1b62003af8565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002d4d5762002d4d62003af8565b60200101906001600160f81b031916908160001a905350600062002d7384600262003b91565b62002d8090600162003bb3565b90505b600181111562002e02576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002db85762002db862003af8565b1a60f81b82828151811062002dd15762002dd162003af8565b60200101906001600160f81b031916908160001a90535060049490941c9362002dfa8162003bc9565b905062002d83565b508315620012d55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000690565b600081815260018301602052604081205462002e9c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000650565b50600062000650565b6000818152600183016020526040812054801562002f9e57600062002ecc60018362003be3565b855490915060009062002ee29060019062003be3565b905081811462002f4e57600086600001828154811062002f065762002f0662003af8565b906000526020600020015490508087600001848154811062002f2c5762002f2c62003af8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002f625762002f6262003bf9565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000650565b600091505062000650565b612a558062003c1083390190565b6040805161012081018252600061010082018181526080830190815260a0830182905260c0830182905260e083019190915291810191825260608082015290819081526020016200301b604051806040016040528060608152602001606081525090565b905290565b6000602082840312156200303357600080fd5b81356001600160e01b031981168114620012d557600080fd5b6001600160a01b038116811462001bee57600080fd5b600080604083850312156200307657600080fd5b823562003083816200304c565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620030cc57620030cc62003091565b60405290565b604051608081016001600160401b0381118282101715620030cc57620030cc62003091565b604051602081016001600160401b0381118282101715620030cc57620030cc62003091565b604051601f8201601f191681016001600160401b038111828210171562003147576200314762003091565b604052919050565b60006001600160401b038211156200316b576200316b62003091565b50601f01601f191660200190565b600082601f8301126200318b57600080fd5b8135620031a26200319c826200314f565b6200311c565b818152846020838601011115620031b857600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215620031ee57600080fd5b85356001600160401b038111156200320557600080fd5b620032138882890162003179565b955050602086013562003226816200304c565b9350604086013562003238816200304c565b925060608601356200324a816200304c565b915060808601356200325c816200304c565b809150509295509295909350565b6000602082840312156200327d57600080fd5b5035919050565b60008083601f8401126200329757600080fd5b5081356001600160401b03811115620032af57600080fd5b602083019150836020828501011115620032c857600080fd5b9250929050565b60008060008060608587031215620032e657600080fd5b84356001600160401b03811115620032fd57600080fd5b6200330b8782880162003284565b909550935050602085013562003321816200304c565b9396929550929360400135925050565b600080604083850312156200334557600080fd5b82359150602083013562003359816200304c565b809150509250929050565b600080602083850312156200337857600080fd5b82356001600160401b038111156200338f57600080fd5b6200339d8582860162003284565b90969095509350505050565b60005b83811015620033c6578181015183820152602001620033ac565b50506000910152565b60008151808452620033e9816020860160208601620033a9565b601f01601f19169290920160200192915050565b602081526000620012d56020830184620033cf565b600080600080606085870312156200342957600080fd5b84356001600160401b038111156200344057600080fd5b6200344e8782880162003284565b909550935050602085013562003464816200304c565b9150604085013562003476816200304c565b939692955090935050565b600080600080606085870312156200349857600080fd5b843593506020850135620034ac816200304c565b925060408501356001600160401b03811115620034c857600080fd5b620034d68782880162003284565b95989497509550505050565b60008060408385031215620034f657600080fd5b50508035926020909101359150565b6000602082840312156200351857600080fd5b8135620012d5816200304c565b6000806000604084860312156200353b57600080fd5b83356001600160401b038111156200355257600080fd5b620035608682870162003284565b909450925050602084013562003576816200304c565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251620035d6818460208701620033a9565b9190910192915050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156200363257600080fd5b81518015158114620012d557600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156200366c57600080fd5b8151620012d5816200304c565b8381526001600160a01b0383166020820152606060408201819052600090620036a590830184620033cf565b95945050505050565b600082620036cc57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115620036e257600080fd5b83861115620036f057600080fd5b5050820193919092039150565b8035600f81106200370d57600080fd5b919050565b6000602082840312156200372557600080fd5b620012d582620036fd565b604081526000620037456040830185620033cf565b8281036020840152620036a58185620033cf565b828152604060208201526000620037746040830184620033cf565b949350505050565b6000602082840312156200378f57600080fd5b81516001600160401b03811115620037a657600080fd5b8201601f81018413620037b857600080fd5b8051620037c96200319c826200314f565b818152856020838501011115620037df57600080fd5b620036a5826020830160208601620033a9565b60008151805151600f81106200381857634e487b7160e01b600052602160045260246000fd5b84526020818101516001600160a01b0390811682870152604080840151909116908601526060918201519185019190915282015160a0608085018190526200377490850182620033cf565b602081526000620012d56020830184620037f2565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620038b2816017850160208801620033a9565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351620038e5816028840160208801620033a9565b01602801949350505050565b600081830360a08112156200390557600080fd5b6200390f620030a7565b915060808112156200392057600080fd5b6200392a620030d2565b60208212156200393957600080fd5b62003943620030f7565b91506200395084620036fd565b825290815260208301359062003966826200304c565b816020820152604084013591506200397e826200304c565b81604082015260608401356060820152808352505060808201356001600160401b03811115620039ad57600080fd5b620039bb8482850162003179565b60208301525092915050565b600060208284031215620039da57600080fd5b81356001600160401b03811115620039f157600080fd5b6200377484828501620038f1565b60006020828403121562003a1257600080fd5b81356001600160401b038082111562003a2a57600080fd5b908301906040828603121562003a3f57600080fd5b62003a49620030a7565b82358281111562003a5957600080fd5b62003a6787828601620038f1565b82525060208301358281111562003a7d57600080fd5b92909201916040838703121562003a9357600080fd5b62003a9d620030a7565b83358381111562003aad57600080fd5b62003abb8882870162003179565b82525060208401358381111562003ad157600080fd5b62003adf8882870162003179565b6020830152508060208301525080935050505092915050565b634e487b7160e01b600052603260045260246000fd5b60208152600082516040602084015262003b2c6060840182620037f2565b90506020840151601f1984830301604085015280516040835262003b546040840182620033cf565b905060208201519150828103602084015262003b718183620033cf565b9695505050505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161562003bae5762003bae62003b7b565b500290565b8082018082111562000650576200065062003b7b565b60008162003bdb5762003bdb62003b7b565b506000190190565b8181038181111562000650576200065062003b7b565b634e487b7160e01b600052603160045260246000fdfe60806040523480156200001157600080fd5b5060405162002a5538038062002a558339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b62000a3c1760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b62000a4b1760201c565b6200013e83836200024660201b62000a741760201c565b62000153620001e860201b62000a4b1760201c565b6200016e60008051602062002a3583398151915280620002b2565b6200018960008051602062002a3583398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60c962000373838262000698565b5060ca62000382828262000698565b505050565b6200039e8282620003c560201b62000aa51760201c565b60008281526097602090815260409091206200038291839062000b2b62000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6122a180620007746000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220f4b1a553d0216fad85e7fc3c0111d94167f74f5dbb1455424ba58f7cf0009cba64736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721WithMetadata.meta.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721WithMetadata.meta.json new file mode 100644 index 000000000..cae2bc804 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerERC721WithMetadata.meta.json @@ -0,0 +1,410 @@ +{ + "name": "TokenManagerERC721WithMetadata", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.dbg.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.dbg.json new file mode 100644 index 000000000..00f5ae209 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.json new file mode 100644 index 000000000..a8c2e8590 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.json @@ -0,0 +1,649 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerEth", + "sourceName": "contracts/schain/TokenManagers/TokenManagerEth.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldValue", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "DepositBoxWasChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "AUTOMATIC_DEPLOY_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + }, + { + "internalType": "address", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "addTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "automaticDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "changeDepositBoxAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "communityLocker", + "outputs": [ + { + "internalType": "contract ICommunityLocker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositBox", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableAutomaticDeploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ethErc20", + "outputs": [ + { + "internalType": "contract IEthErc20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exitToMain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newChainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + }, + { + "internalType": "contract IEthErc20", + "name": "ethErc20Address", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newSchainName", + "type": "string" + }, + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxy", + "type": "address" + }, + { + "internalType": "contract ITokenManagerLinker", + "name": "newIMALinker", + "type": "address" + }, + { + "internalType": "contract ICommunityLocker", + "name": "newCommunityLocker", + "type": "address" + }, + { + "internalType": "address", + "name": "newDepositBox", + "type": "address" + } + ], + "name": "initializeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "fromChainHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "postMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "schainHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IEthErc20", + "name": "newEthErc20Address", + "type": "address" + } + ], + "name": "setEthErc20Address", + "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": "tokenManagerLinker", + "outputs": [ + { + "internalType": "contract ITokenManagerLinker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50612137806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638182e7071161010f578063c0e312dc116100a2578063d547741f11610071578063d547741f1461046c578063dec2deb61461047f578063edcc12b514610493578063eeeb9601146104a657600080fd5b8063c0e312dc1461040c578063ca15c8731461041f578063cb703bff14610432578063cc5b715b1461044557600080fd5b806391d14854116100de57806391d14854146103d657806392d7846a146103e9578063a217fddf146103fc578063b9581c501461040457600080fd5b80638182e7071461038a578063884cee5a1461039d5780638b71b4b5146103b05780639010d07c146103c357600080fd5b806339927cf9116101875780635573b8b6116101565780635573b8b61461033e5780636ce681d2146103515780636d611286146103645780636d6c68e61461037757600080fd5b806339927cf9146102da5780633b690b6b146102ed5780633fa194ce146102f657806350f442801461030b57600080fd5b806328c5e182116101c357806328c5e182146102995780632dc151de146102a15780632f2ff15d146102b457806336568abe146102c757600080fd5b806301ffc9a7146101f5578063029996b81461021d5780630f1a8f7414610227578063248a9ca314610268575b600080fd5b610208610203366004611904565b6104b9565b60405190151581526020015b60405180910390f35b6102256104e4565b005b61025061023536600461192e565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610214565b61028b61027636600461192e565b60009081526065602052604090206001015490565b604051908152602001610214565b61028b610536565b60ca54610250906001600160a01b031681565b6102256102c236600461195c565b61057f565b6102256102d536600461195c565b6105a9565b6102086102e83660046119d5565b610627565b61028b60cc5481565b61028b6000805160206120e283398151915281565b6103316040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516102149190611a67565b60c954610250906001600160a01b031681565b61022561035f366004611b1d565b610682565b60cd54610250906001600160a01b031681565b60cb54610250906001600160a01b031681565b610225610398366004611ba7565b61089b565b6102256103ab366004611c42565b61098b565b6102256103be366004611c9e565b610b1e565b6102506103d1366004611cbb565b610bba565b6102086103e436600461195c565b610bd9565b60cf54610250906001600160a01b031681565b61028b600081565b610225610c04565b61022561041a3660046119d5565b610c47565b61028b61042d36600461192e565b610d34565b610225610440366004611cdd565b610d4b565b61028b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b61022561047a36600461195c565b610e9f565b60cd5461020890600160a01b900460ff1681565b6102256104a1366004611c9e565b610ec4565b6102256104b436600461192e565b610fda565b60006001600160e01b03198216635a05180f60e01b14806104de57506104de826110e8565b92915050565b6104fc6000805160206120e283398151915233610bd9565b6105215760405162461bcd60e51b815260040161051890611d34565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016105669190611d75565b6040516020818303038152906040528051906020012081565b60008281526065602052604090206001015461059a8161111d565b6105a48383611127565b505050565b6001600160a01b03811633146106195760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610518565b6106238282611149565b5050565b6000806001600160a01b031660ce6000858560405160200161064a929190611d91565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b600054610100900460ff16158080156106a25750600054600160ff909116105b806106bc5750303b1580156106bc575060005460ff166001145b6106d85760405162461bcd60e51b815260040161051890611da1565b6000805460ff1916600117905580156106fb576000805461ff0019166101001790555b6001600160a01b0382166107515760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401610518565b61075961116b565b6107646000336111d8565b61077c6000805160206120e2833981519152336111d8565b6107a67ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba8336111d8565b856040516020016107b79190611d75565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a18015610893576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b600054610100900460ff16158080156108bb5750600054600160ff909116105b806108d55750303b1580156108d5575060005460ff166001145b6108f15760405162461bcd60e51b815260040161051890611da1565b6000805460ff191660011790558015610914576000805461ff0019166101001790555b6109218787878787610682565b60cf80546001600160a01b0319166001600160a01b0384161790558015610982576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60c9546001600160a01b031633146109e55760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f7879000000006044820152606401610518565b838360cc5482141580156109fe57506109fe82826111e2565b610a4a5760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f727265637400000000006044820152606401610518565b6000610a56858561124a565b60208101519091506001600160a01b038116610aa95760405162461bcd60e51b815260206004820152601260248201527124b731b7b93932b1ba103932b1b2b4bb32b960711b6044820152606401610518565b60cf5460408381015190516340c10f1960e01b81526001600160a01b03848116600483015260248201929092529116906340c10f1990604401600060405180830381600087803b158015610afc57600080fd5b505af1158015610b10573d6000803e3d6000fd5b505050505050505050505050565b610b29600033610bd9565b610b455760405162461bcd60e51b815260040161051890611def565b60cf546001600160a01b03808316911603610b985760405162461bcd60e51b81526020600482015260136024820152724d757374206265206e6577206164647265737360681b6044820152606401610518565b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152609760205260408120610bd290836112e3565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610c1c6000805160206120e283398151915233610bd9565b610c385760405162461bcd60e51b815260040161051890611d34565b60cd805460ff60a01b19169055565b60ca546001600160a01b0316331480610c665750610c66600033610bd9565b610c825760405162461bcd60e51b815260040161051890611def565b60008282604051602001610c97929190611d91565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316610d145760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f742073657400000000000000006044820152606401610518565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206104de906112ef565b60ca546001600160a01b0316331480610d6a5750610d6a600033610bd9565b610d865760405162461bcd60e51b815260040161051890611def565b60008383604051602001610d9b929190611d91565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615610e195760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c726561647920736574000000006044820152606401610518565b6001600160a01b038216610e6f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401610518565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b600082815260656020526040902060010154610eba8161111d565b6105a48383611149565b610ecf600033610bd9565b610f1b5760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401610518565b6001600160a01b038116610f715760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401610518565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929261101d929101611d75565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b15801561106f57600080fd5b505af1158015611083573d6000803e3d6000fd5b505050506110e56040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016110ba9190611d75565b60408051601f19818403018152919052805160209091012060cd546001600160a01b031633846112f9565b50565b60006001600160e01b03198216637965db0b60e01b14806104de57506301ffc9a760e01b6001600160e01b03198316146104de565b6110e581336113de565b6111318282611442565b60008281526097602052604090206105a490826114c8565b61115382826114dd565b60008281526097602052604090206105a49082611544565b600054610100900460ff166111d65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610518565b565b6106238282611127565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016112149190611d75565b6040516020818303038152906040528051906020012083148015610bd257505060cd546001600160a01b03908116911614919050565b604080516080810182526000606082018181528252602082018190529181019190915260016112798484611559565b600e81111561128a5761128a611e1e565b146112d75760405162461bcd60e51b815260206004820181905260248201527f4d6573736167652074797065206973206e6f7420455448207472616e736665726044820152606401610518565b610bd282840184611e48565b6000610bd283836115a4565b60006104de825490565b80156113645760cf546040516338b5bd8d60e21b8152336004820152602481018390526001600160a01b039091169063e2d6f63490604401600060405180830381600087803b15801561134b57600080fd5b505af115801561135f573d6000803e3d6000fd5b505050505b600061137083836115ce565b60c954604051634a24490160e11b81529192506001600160a01b0316906394489202906113a590889088908690600401611ee8565b600060405180830381600087803b1580156113bf57600080fd5b505af11580156113d3573d6000803e3d6000fd5b505050505050505050565b6113e88282610bd9565b61062357611400816001600160a01b03166014611626565b61140b836020611626565b60405160200161141c929190611f1b565b60408051601f198184030181529082905262461bcd60e51b825261051891600401611a67565b61144c8282610bd9565b6106235760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556114843390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610bd2836001600160a01b0384166117c2565b6114e78282610bd9565b156106235760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610bd2836001600160a01b038416611811565b6000806115688385018561192e565b9050611575602082611f90565b6000036115985761159061158b84838188611fb2565b611559565b9150506104de565b61159083850185611fdc565b60008260000182815481106115bb576115bb611ff7565b9060005260206000200154905092915050565b60408051608081018252600160608083019182529082526001600160a01b0385166020808401919091528284018590529251909261160e9183910161200d565b60405160208183030381529060405291505092915050565b6060600061163583600261206f565b61164090600261208e565b67ffffffffffffffff81111561165857611658611a7a565b6040519080825280601f01601f191660200182016040528015611682576020820181803683370190505b509050600360fc1b8160008151811061169d5761169d611ff7565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106116cc576116cc611ff7565b60200101906001600160f81b031916908160001a90535060006116f084600261206f565b6116fb90600161208e565b90505b6001811115611773576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061172f5761172f611ff7565b1a60f81b82828151811061174557611745611ff7565b60200101906001600160f81b031916908160001a90535060049490941c9361176c816120a1565b90506116fe565b508315610bd25760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610518565b6000818152600183016020526040812054611809575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104de565b5060006104de565b600081815260018301602052604081205480156118fa5760006118356001836120b8565b8554909150600090611849906001906120b8565b90508181146118ae57600086600001828154811061186957611869611ff7565b906000526020600020015490508087600001848154811061188c5761188c611ff7565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118bf576118bf6120cb565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104de565b60009150506104de565b60006020828403121561191657600080fd5b81356001600160e01b031981168114610bd257600080fd5b60006020828403121561194057600080fd5b5035919050565b6001600160a01b03811681146110e557600080fd5b6000806040838503121561196f57600080fd5b82359150602083013561198181611947565b809150509250929050565b60008083601f84011261199e57600080fd5b50813567ffffffffffffffff8111156119b657600080fd5b6020830191508360208285010111156119ce57600080fd5b9250929050565b600080602083850312156119e857600080fd5b823567ffffffffffffffff8111156119ff57600080fd5b611a0b8582860161198c565b90969095509350505050565b60005b83811015611a32578181015183820152602001611a1a565b50506000910152565b60008151808452611a53816020860160208601611a17565b601f01601f19169290920160200192915050565b602081526000610bd26020830184611a3b565b634e487b7160e01b600052604160045260246000fd5b600082601f830112611aa157600080fd5b813567ffffffffffffffff80821115611abc57611abc611a7a565b604051601f8301601f19908116603f01168101908282118183101715611ae457611ae4611a7a565b81604052838152866020858801011115611afd57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a08688031215611b3557600080fd5b853567ffffffffffffffff811115611b4c57600080fd5b611b5888828901611a90565b9550506020860135611b6981611947565b93506040860135611b7981611947565b92506060860135611b8981611947565b91506080860135611b9981611947565b809150509295509295909350565b60008060008060008060c08789031215611bc057600080fd5b863567ffffffffffffffff811115611bd757600080fd5b611be389828a01611a90565b9650506020870135611bf481611947565b94506040870135611c0481611947565b93506060870135611c1481611947565b92506080870135611c2481611947565b915060a0870135611c3481611947565b809150509295509295509295565b60008060008060608587031215611c5857600080fd5b843593506020850135611c6a81611947565b9250604085013567ffffffffffffffff811115611c8657600080fd5b611c928782880161198c565b95989497509550505050565b600060208284031215611cb057600080fd5b8135610bd281611947565b60008060408385031215611cce57600080fd5b50508035926020909101359150565b600080600060408486031215611cf257600080fd5b833567ffffffffffffffff811115611d0957600080fd5b611d158682870161198c565b9094509250506020840135611d2981611947565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251611d87818460208701611a17565b9190910192915050565b8183823760009101908152919050565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b8035600f8110611e4357600080fd5b919050565b60008183036060811215611e5b57600080fd5b6040516060810167ffffffffffffffff8282108183111715611e7f57611e7f611a7a565b816040526020841215611e9157600080fd5b6080830193508184108185111715611eab57611eab611a7a565b5082604052611eb985611e34565b8152815260208401359150611ecd82611947565b81602082015260408401356040820152809250505092915050565b8381526001600160a01b0383166020820152606060408201819052600090611f1290830184611a3b565b95945050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611f53816017850160208801611a17565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611f84816028840160208801611a17565b01602801949350505050565b600082611fad57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115611fc257600080fd5b83861115611fcf57600080fd5b5050820193919092039150565b600060208284031215611fee57600080fd5b610bd282611e34565b634e487b7160e01b600052603260045260246000fd5b8151516060820190600f811061203357634e487b7160e01b600052602160045260246000fd5b82526020838101516001600160a01b031690830152604092830151929091019190915290565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561208957612089612059565b500290565b808201808211156104de576104de612059565b6000816120b0576120b0612059565b506000190190565b818103818111156104de576104de612059565b634e487b7160e01b600052603160045260246000fdfe7164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220ea530cdb7a3468cc605b8922313d6c065d2db0cde0a03bc2ff50f292214a3bb664736f6c63430008100033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80638182e7071161010f578063c0e312dc116100a2578063d547741f11610071578063d547741f1461046c578063dec2deb61461047f578063edcc12b514610493578063eeeb9601146104a657600080fd5b8063c0e312dc1461040c578063ca15c8731461041f578063cb703bff14610432578063cc5b715b1461044557600080fd5b806391d14854116100de57806391d14854146103d657806392d7846a146103e9578063a217fddf146103fc578063b9581c501461040457600080fd5b80638182e7071461038a578063884cee5a1461039d5780638b71b4b5146103b05780639010d07c146103c357600080fd5b806339927cf9116101875780635573b8b6116101565780635573b8b61461033e5780636ce681d2146103515780636d611286146103645780636d6c68e61461037757600080fd5b806339927cf9146102da5780633b690b6b146102ed5780633fa194ce146102f657806350f442801461030b57600080fd5b806328c5e182116101c357806328c5e182146102995780632dc151de146102a15780632f2ff15d146102b457806336568abe146102c757600080fd5b806301ffc9a7146101f5578063029996b81461021d5780630f1a8f7414610227578063248a9ca314610268575b600080fd5b610208610203366004611904565b6104b9565b60405190151581526020015b60405180910390f35b6102256104e4565b005b61025061023536600461192e565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610214565b61028b61027636600461192e565b60009081526065602052604090206001015490565b604051908152602001610214565b61028b610536565b60ca54610250906001600160a01b031681565b6102256102c236600461195c565b61057f565b6102256102d536600461195c565b6105a9565b6102086102e83660046119d5565b610627565b61028b60cc5481565b61028b6000805160206120e283398151915281565b6103316040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516102149190611a67565b60c954610250906001600160a01b031681565b61022561035f366004611b1d565b610682565b60cd54610250906001600160a01b031681565b60cb54610250906001600160a01b031681565b610225610398366004611ba7565b61089b565b6102256103ab366004611c42565b61098b565b6102256103be366004611c9e565b610b1e565b6102506103d1366004611cbb565b610bba565b6102086103e436600461195c565b610bd9565b60cf54610250906001600160a01b031681565b61028b600081565b610225610c04565b61022561041a3660046119d5565b610c47565b61028b61042d36600461192e565b610d34565b610225610440366004611cdd565b610d4b565b61028b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b61022561047a36600461195c565b610e9f565b60cd5461020890600160a01b900460ff1681565b6102256104a1366004611c9e565b610ec4565b6102256104b436600461192e565b610fda565b60006001600160e01b03198216635a05180f60e01b14806104de57506104de826110e8565b92915050565b6104fc6000805160206120e283398151915233610bd9565b6105215760405162461bcd60e51b815260040161051890611d34565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016105669190611d75565b6040516020818303038152906040528051906020012081565b60008281526065602052604090206001015461059a8161111d565b6105a48383611127565b505050565b6001600160a01b03811633146106195760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610518565b6106238282611149565b5050565b6000806001600160a01b031660ce6000858560405160200161064a929190611d91565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b600054610100900460ff16158080156106a25750600054600160ff909116105b806106bc5750303b1580156106bc575060005460ff166001145b6106d85760405162461bcd60e51b815260040161051890611da1565b6000805460ff1916600117905580156106fb576000805461ff0019166101001790555b6001600160a01b0382166107515760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401610518565b61075961116b565b6107646000336111d8565b61077c6000805160206120e2833981519152336111d8565b6107a67ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba8336111d8565b856040516020016107b79190611d75565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a18015610893576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b600054610100900460ff16158080156108bb5750600054600160ff909116105b806108d55750303b1580156108d5575060005460ff166001145b6108f15760405162461bcd60e51b815260040161051890611da1565b6000805460ff191660011790558015610914576000805461ff0019166101001790555b6109218787878787610682565b60cf80546001600160a01b0319166001600160a01b0384161790558015610982576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60c9546001600160a01b031633146109e55760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f7879000000006044820152606401610518565b838360cc5482141580156109fe57506109fe82826111e2565b610a4a5760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f727265637400000000006044820152606401610518565b6000610a56858561124a565b60208101519091506001600160a01b038116610aa95760405162461bcd60e51b815260206004820152601260248201527124b731b7b93932b1ba103932b1b2b4bb32b960711b6044820152606401610518565b60cf5460408381015190516340c10f1960e01b81526001600160a01b03848116600483015260248201929092529116906340c10f1990604401600060405180830381600087803b158015610afc57600080fd5b505af1158015610b10573d6000803e3d6000fd5b505050505050505050505050565b610b29600033610bd9565b610b455760405162461bcd60e51b815260040161051890611def565b60cf546001600160a01b03808316911603610b985760405162461bcd60e51b81526020600482015260136024820152724d757374206265206e6577206164647265737360681b6044820152606401610518565b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152609760205260408120610bd290836112e3565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610c1c6000805160206120e283398151915233610bd9565b610c385760405162461bcd60e51b815260040161051890611d34565b60cd805460ff60a01b19169055565b60ca546001600160a01b0316331480610c665750610c66600033610bd9565b610c825760405162461bcd60e51b815260040161051890611def565b60008282604051602001610c97929190611d91565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316610d145760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f742073657400000000000000006044820152606401610518565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206104de906112ef565b60ca546001600160a01b0316331480610d6a5750610d6a600033610bd9565b610d865760405162461bcd60e51b815260040161051890611def565b60008383604051602001610d9b929190611d91565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615610e195760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c726561647920736574000000006044820152606401610518565b6001600160a01b038216610e6f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401610518565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b600082815260656020526040902060010154610eba8161111d565b6105a48383611149565b610ecf600033610bd9565b610f1b5760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401610518565b6001600160a01b038116610f715760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401610518565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929261101d929101611d75565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b15801561106f57600080fd5b505af1158015611083573d6000803e3d6000fd5b505050506110e56040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016110ba9190611d75565b60408051601f19818403018152919052805160209091012060cd546001600160a01b031633846112f9565b50565b60006001600160e01b03198216637965db0b60e01b14806104de57506301ffc9a760e01b6001600160e01b03198316146104de565b6110e581336113de565b6111318282611442565b60008281526097602052604090206105a490826114c8565b61115382826114dd565b60008281526097602052604090206105a49082611544565b600054610100900460ff166111d65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610518565b565b6106238282611127565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016112149190611d75565b6040516020818303038152906040528051906020012083148015610bd257505060cd546001600160a01b03908116911614919050565b604080516080810182526000606082018181528252602082018190529181019190915260016112798484611559565b600e81111561128a5761128a611e1e565b146112d75760405162461bcd60e51b815260206004820181905260248201527f4d6573736167652074797065206973206e6f7420455448207472616e736665726044820152606401610518565b610bd282840184611e48565b6000610bd283836115a4565b60006104de825490565b80156113645760cf546040516338b5bd8d60e21b8152336004820152602481018390526001600160a01b039091169063e2d6f63490604401600060405180830381600087803b15801561134b57600080fd5b505af115801561135f573d6000803e3d6000fd5b505050505b600061137083836115ce565b60c954604051634a24490160e11b81529192506001600160a01b0316906394489202906113a590889088908690600401611ee8565b600060405180830381600087803b1580156113bf57600080fd5b505af11580156113d3573d6000803e3d6000fd5b505050505050505050565b6113e88282610bd9565b61062357611400816001600160a01b03166014611626565b61140b836020611626565b60405160200161141c929190611f1b565b60408051601f198184030181529082905262461bcd60e51b825261051891600401611a67565b61144c8282610bd9565b6106235760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556114843390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610bd2836001600160a01b0384166117c2565b6114e78282610bd9565b156106235760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610bd2836001600160a01b038416611811565b6000806115688385018561192e565b9050611575602082611f90565b6000036115985761159061158b84838188611fb2565b611559565b9150506104de565b61159083850185611fdc565b60008260000182815481106115bb576115bb611ff7565b9060005260206000200154905092915050565b60408051608081018252600160608083019182529082526001600160a01b0385166020808401919091528284018590529251909261160e9183910161200d565b60405160208183030381529060405291505092915050565b6060600061163583600261206f565b61164090600261208e565b67ffffffffffffffff81111561165857611658611a7a565b6040519080825280601f01601f191660200182016040528015611682576020820181803683370190505b509050600360fc1b8160008151811061169d5761169d611ff7565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106116cc576116cc611ff7565b60200101906001600160f81b031916908160001a90535060006116f084600261206f565b6116fb90600161208e565b90505b6001811115611773576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061172f5761172f611ff7565b1a60f81b82828151811061174557611745611ff7565b60200101906001600160f81b031916908160001a90535060049490941c9361176c816120a1565b90506116fe565b508315610bd25760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610518565b6000818152600183016020526040812054611809575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104de565b5060006104de565b600081815260018301602052604081205480156118fa5760006118356001836120b8565b8554909150600090611849906001906120b8565b90508181146118ae57600086600001828154811061186957611869611ff7565b906000526020600020015490508087600001848154811061188c5761188c611ff7565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118bf576118bf6120cb565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104de565b60009150506104de565b60006020828403121561191657600080fd5b81356001600160e01b031981168114610bd257600080fd5b60006020828403121561194057600080fd5b5035919050565b6001600160a01b03811681146110e557600080fd5b6000806040838503121561196f57600080fd5b82359150602083013561198181611947565b809150509250929050565b60008083601f84011261199e57600080fd5b50813567ffffffffffffffff8111156119b657600080fd5b6020830191508360208285010111156119ce57600080fd5b9250929050565b600080602083850312156119e857600080fd5b823567ffffffffffffffff8111156119ff57600080fd5b611a0b8582860161198c565b90969095509350505050565b60005b83811015611a32578181015183820152602001611a1a565b50506000910152565b60008151808452611a53816020860160208601611a17565b601f01601f19169290920160200192915050565b602081526000610bd26020830184611a3b565b634e487b7160e01b600052604160045260246000fd5b600082601f830112611aa157600080fd5b813567ffffffffffffffff80821115611abc57611abc611a7a565b604051601f8301601f19908116603f01168101908282118183101715611ae457611ae4611a7a565b81604052838152866020858801011115611afd57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a08688031215611b3557600080fd5b853567ffffffffffffffff811115611b4c57600080fd5b611b5888828901611a90565b9550506020860135611b6981611947565b93506040860135611b7981611947565b92506060860135611b8981611947565b91506080860135611b9981611947565b809150509295509295909350565b60008060008060008060c08789031215611bc057600080fd5b863567ffffffffffffffff811115611bd757600080fd5b611be389828a01611a90565b9650506020870135611bf481611947565b94506040870135611c0481611947565b93506060870135611c1481611947565b92506080870135611c2481611947565b915060a0870135611c3481611947565b809150509295509295509295565b60008060008060608587031215611c5857600080fd5b843593506020850135611c6a81611947565b9250604085013567ffffffffffffffff811115611c8657600080fd5b611c928782880161198c565b95989497509550505050565b600060208284031215611cb057600080fd5b8135610bd281611947565b60008060408385031215611cce57600080fd5b50508035926020909101359150565b600080600060408486031215611cf257600080fd5b833567ffffffffffffffff811115611d0957600080fd5b611d158682870161198c565b9094509250506020840135611d2981611947565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251611d87818460208701611a17565b9190910192915050565b8183823760009101908152919050565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b8035600f8110611e4357600080fd5b919050565b60008183036060811215611e5b57600080fd5b6040516060810167ffffffffffffffff8282108183111715611e7f57611e7f611a7a565b816040526020841215611e9157600080fd5b6080830193508184108185111715611eab57611eab611a7a565b5082604052611eb985611e34565b8152815260208401359150611ecd82611947565b81602082015260408401356040820152809250505092915050565b8381526001600160a01b0383166020820152606060408201819052600090611f1290830184611a3b565b95945050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611f53816017850160208801611a17565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611f84816028840160208801611a17565b01602801949350505050565b600082611fad57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115611fc257600080fd5b83861115611fcf57600080fd5b5050820193919092039150565b600060208284031215611fee57600080fd5b610bd282611e34565b634e487b7160e01b600052603260045260246000fd5b8151516060820190600f811061203357634e487b7160e01b600052602160045260246000fd5b82526020838101516001600160a01b031690830152604092830151929091019190915290565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561208957612089612059565b500290565b808201808211156104de576104de612059565b6000816120b0576120b0612059565b506000190190565b818103818111156104de576104de612059565b634e487b7160e01b600052603160045260246000fdfe7164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220ea530cdb7a3468cc605b8922313d6c065d2db0cde0a03bc2ff50f292214a3bb664736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.meta.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.meta.json new file mode 100644 index 000000000..c91e39e2c --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerEth.meta.json @@ -0,0 +1,410 @@ +{ + "name": "TokenManagerEth", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.dbg.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.dbg.json new file mode 100644 index 000000000..8431fa57a --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.dbg.json @@ -0,0 +1,4 @@ +{ + "_format": "hh-sol-dbg-1", + "buildInfo": "../../../build-info/09335595e801237ae04fc28c9dd0abe9.json" +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.json new file mode 100644 index 000000000..520360112 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.json @@ -0,0 +1,463 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TokenManagerLinker", + "sourceName": "contracts/schain/TokenManagerLinker.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAINNET_NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REGISTRAR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "connectSchain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "disconnectSchain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "schainName", + "type": "string" + } + ], + "name": "hasSchain", + "outputs": [ + { + "internalType": "bool", + "name": "connected", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITokenManager", + "name": "tokenManager", + "type": "address" + } + ], + "name": "hasTokenManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "newMessageProxyAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "linker", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "linkerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messageProxy", + "outputs": [ + { + "internalType": "contract IMessageProxyForSchain", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITokenManager", + "name": "newTokenManager", + "type": "address" + } + ], + "name": "registerTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITokenManager", + "name": "tokenManagerAddress", + "type": "address" + } + ], + "name": "removeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "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": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenManagers", + "outputs": [ + { + "internalType": "contract ITokenManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b506116ea806100206000396000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c80635573b8b6116100b8578063a217fddf1161007c578063a217fddf146102d9578063b9727f96146102e1578063ca15c873146102f4578063d547741f14610307578063e953c9921461031a578063f68e95531461032d57600080fd5b80635573b8b61461027a57806364a5142f1461028d5780639010d07c146102a057806391d14854146102b3578063990c85e6146102c657600080fd5b8063291f60d31161010a578063291f60d3146101d05780632f2ff15d146101e357806336568abe146101f657806341ecadf914610209578063485cc9551461023457806350f442801461024757600080fd5b806301ffc9a714610147578063041f4c9b1461016f578063173df64b14610182578063248a9ca31461019757806328c5e182146101c8575b600080fd5b61015a6101553660046112b6565b610342565b60405190151581526020015b60405180910390f35b61015a61017d3660046112e0565b61036d565b6101956101903660046112e0565b6104ad565b005b6101ba6101a5366004611352565b60009081526065602052604090206001015490565b604051908152602001610166565b6101ba6105f5565b6101956101de366004611380565b61063e565b6101956101f136600461139d565b6106c4565b61019561020436600461139d565b6106ee565b61021c610217366004611352565b61076c565b6040516001600160a01b039091168152602001610166565b6101956102423660046113cd565b610796565b61026d6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051610166919061141f565b60c95461021c906001600160a01b031681565b60ca5461021c906001600160a01b031681565b61021c6102ae366004611452565b61095b565b61015a6102c136600461139d565b61097a565b6101956102d43660046112e0565b6109a5565b6101ba600081565b6101956102ef366004611380565b610b20565b6101ba610302366004611352565b610c76565b61019561031536600461139d565b610c8d565b61015a610328366004611380565b610cb2565b6101ba60008051602061169583398151915281565b60006001600160e01b03198216635a05180f60e01b1480610367575061036782610d20565b92915050565b60cb5460019060005b8181101561042957828015610415575060cb818154811061039957610399611474565b6000918252602090912001546040516339927cf960e01b81526001600160a01b03909116906339927cf9906103d490889088906004016114b3565b602060405180830381865afa1580156103f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041591906114c7565b925080610421816114ff565b915050610376565b508180156104a5575060c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9061046490879087906004016114b3565b602060405180830381865afa158015610481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a591906114c7565b949350505050565b6104c56000805160206116958339815191523361097a565b6104ea5760405162461bcd60e51b81526004016104e190611518565b60405180910390fd5b60cb5460005b8181101561058b5760cb818154811061050b5761050b611474565b600091825260209091200154604051633038c4b760e21b81526001600160a01b039091169063c0e312dc9061054690879087906004016114b3565b600060405180830381600087803b15801561056057600080fd5b505af1158015610574573d6000803e3d6000fd5b505050508080610583906114ff565b9150506104f0565b5060c954604051633cdd2cc360e01b81526001600160a01b0390911690633cdd2cc3906105be90869086906004016114b3565b600060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b50505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610625919061154f565b6040516020818303038152906040528051906020012081565b6106566000805160206116958339815191523361097a565b6106725760405162461bcd60e51b81526004016104e190611518565b60cb80546001810182556000919091527fa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fb0180546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152606560205260409020600101546106df81610d55565b6106e98383610d62565b505050565b6001600160a01b038116331461075e5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016104e1565b6107688282610d84565b5050565b60cb818154811061077c57600080fd5b6000918252602090912001546001600160a01b0316905081565b600054610100900460ff16158080156107b65750600054600160ff909116105b806107d05750303b1580156107d0575060005460ff166001145b6108335760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104e1565b6000805460ff191660011790558015610856576000805461ff0019166101001790555b6001600160a01b0382166108ac5760405162461bcd60e51b815260206004820152601c60248201527f4c696e6b657220616464726573732068617320746f206265207365740000000060448201526064016104e1565b6108b4610da6565b6108bf600033610e13565b6108d760008051602061169583398151915233610e13565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca80549285169290911691909117905560cc805460ff1916905580156106e9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60008281526097602052604081206109739083610e1d565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6109bd6000805160206116958339815191523361097a565b6109d95760405162461bcd60e51b81526004016104e190611518565b60005b60cb54811015610ab75760cb81815481106109f9576109f9611474565b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663cb703bff848460cb8581548110610a3a57610a3a611474565b6000918252602090912001546040516001600160e01b031960e086901b168152610a729392916001600160a01b03169060040161156b565b600060405180830381600087803b158015610a8c57600080fd5b505af1158015610aa0573d6000803e3d6000fd5b505050508080610aaf906114ff565b9150506109dc565b5060c95460405163f2f6360560e01b81526001600160a01b039091169063f2f6360590610aea90859085906004016114b3565b600060405180830381600087803b158015610b0457600080fd5b505af1158015610b18573d6000803e3d6000fd5b505050505050565b610b386000805160206116958339815191523361097a565b610b545760405162461bcd60e51b81526004016104e190611518565b60cb546000905b80821015610bac57826001600160a01b031660cb8381548110610b8057610b80611474565b6000918252602090912001546001600160a01b031614610bac5781610ba4816114ff565b925050610b5b565b808210156106e957610bbf600182611597565b821015610c3e5760cb610bd3600183611597565b81548110610be357610be3611474565b60009182526020909120015460cb80546001600160a01b039092169184908110610c0f57610c0f611474565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b60cb805480610c4f57610c4f6115aa565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b600081815260976020526040812061036790610e29565b600082815260656020526040902060010154610ca881610d55565b6106e98383610d84565b60cb5460009081905b80821015610d1657836001600160a01b031660cb8381548110610ce057610ce0611474565b6000918252602090912001546001600160a01b031603610d04575060019392505050565b81610d0e816114ff565b925050610cbb565b5060009392505050565b60006001600160e01b03198216637965db0b60e01b148061036757506301ffc9a760e01b6001600160e01b0319831614610367565b610d5f8133610e33565b50565b610d6c8282610e97565b60008281526097602052604090206106e99082610f1d565b610d8e8282610f32565b60008281526097602052604090206106e99082610f99565b600054610100900460ff16610e115760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104e1565b565b6107688282610d62565b60006109738383610fae565b6000610367825490565b610e3d828261097a565b61076857610e55816001600160a01b03166014610fd8565b610e60836020610fd8565b604051602001610e719291906115c0565b60408051601f198184030181529082905262461bcd60e51b82526104e19160040161141f565b610ea1828261097a565b6107685760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ed93390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610973836001600160a01b038416611174565b610f3c828261097a565b156107685760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610973836001600160a01b0384166111c3565b6000826000018281548110610fc557610fc5611474565b9060005260206000200154905092915050565b60606000610fe7836002611635565b610ff2906002611654565b67ffffffffffffffff81111561100a5761100a611667565b6040519080825280601f01601f191660200182016040528015611034576020820181803683370190505b509050600360fc1b8160008151811061104f5761104f611474565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061107e5761107e611474565b60200101906001600160f81b031916908160001a90535060006110a2846002611635565b6110ad906001611654565b90505b6001811115611125576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110e1576110e1611474565b1a60f81b8282815181106110f7576110f7611474565b60200101906001600160f81b031916908160001a90535060049490941c9361111e8161167d565b90506110b0565b5083156109735760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016104e1565b60008181526001830160205260408120546111bb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610367565b506000610367565b600081815260018301602052604081205480156112ac5760006111e7600183611597565b85549091506000906111fb90600190611597565b905081811461126057600086600001828154811061121b5761121b611474565b906000526020600020015490508087600001848154811061123e5761123e611474565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611271576112716115aa565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610367565b6000915050610367565b6000602082840312156112c857600080fd5b81356001600160e01b03198116811461097357600080fd5b600080602083850312156112f357600080fd5b823567ffffffffffffffff8082111561130b57600080fd5b818501915085601f83011261131f57600080fd5b81358181111561132e57600080fd5b86602082850101111561134057600080fd5b60209290920196919550909350505050565b60006020828403121561136457600080fd5b5035919050565b6001600160a01b0381168114610d5f57600080fd5b60006020828403121561139257600080fd5b81356109738161136b565b600080604083850312156113b057600080fd5b8235915060208301356113c28161136b565b809150509250929050565b600080604083850312156113e057600080fd5b82356113eb8161136b565b915060208301356113c28161136b565b60005b838110156114165781810151838201526020016113fe565b50506000910152565b602081526000825180602084015261143e8160408501602087016113fb565b601f01601f19169190910160400192915050565b6000806040838503121561146557600080fd5b50508035926020909101359150565b634e487b7160e01b600052603260045260246000fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006104a560208301848661148a565b6000602082840312156114d957600080fd5b8151801515811461097357600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611511576115116114e9565b5060010190565b6020808252601a908201527f5245474953545241525f524f4c45206973207265717569726564000000000000604082015260600190565b600082516115618184602087016113fb565b9190910192915050565b60408152600061157f60408301858761148a565b905060018060a01b0383166020830152949350505050565b81810381811115610367576103676114e9565b634e487b7160e01b600052603160045260246000fd5b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516115f88160178501602088016113fb565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516116298160288401602088016113fb565b01602801949350505050565b600081600019048311821515161561164f5761164f6114e9565b500290565b80820180821115610367576103676114e9565b634e487b7160e01b600052604160045260246000fd5b60008161168c5761168c6114e9565b50600019019056feedcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c309238a26469706673582212205c3ac6ab85f1fd2aa105748f1966cb6a752e6f4f19ee82ab54ceea3706fb192a64736f6c63430008100033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101425760003560e01c80635573b8b6116100b8578063a217fddf1161007c578063a217fddf146102d9578063b9727f96146102e1578063ca15c873146102f4578063d547741f14610307578063e953c9921461031a578063f68e95531461032d57600080fd5b80635573b8b61461027a57806364a5142f1461028d5780639010d07c146102a057806391d14854146102b3578063990c85e6146102c657600080fd5b8063291f60d31161010a578063291f60d3146101d05780632f2ff15d146101e357806336568abe146101f657806341ecadf914610209578063485cc9551461023457806350f442801461024757600080fd5b806301ffc9a714610147578063041f4c9b1461016f578063173df64b14610182578063248a9ca31461019757806328c5e182146101c8575b600080fd5b61015a6101553660046112b6565b610342565b60405190151581526020015b60405180910390f35b61015a61017d3660046112e0565b61036d565b6101956101903660046112e0565b6104ad565b005b6101ba6101a5366004611352565b60009081526065602052604090206001015490565b604051908152602001610166565b6101ba6105f5565b6101956101de366004611380565b61063e565b6101956101f136600461139d565b6106c4565b61019561020436600461139d565b6106ee565b61021c610217366004611352565b61076c565b6040516001600160a01b039091168152602001610166565b6101956102423660046113cd565b610796565b61026d6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051610166919061141f565b60c95461021c906001600160a01b031681565b60ca5461021c906001600160a01b031681565b61021c6102ae366004611452565b61095b565b61015a6102c136600461139d565b61097a565b6101956102d43660046112e0565b6109a5565b6101ba600081565b6101956102ef366004611380565b610b20565b6101ba610302366004611352565b610c76565b61019561031536600461139d565b610c8d565b61015a610328366004611380565b610cb2565b6101ba60008051602061169583398151915281565b60006001600160e01b03198216635a05180f60e01b1480610367575061036782610d20565b92915050565b60cb5460019060005b8181101561042957828015610415575060cb818154811061039957610399611474565b6000918252602090912001546040516339927cf960e01b81526001600160a01b03909116906339927cf9906103d490889088906004016114b3565b602060405180830381865afa1580156103f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041591906114c7565b925080610421816114ff565b915050610376565b508180156104a5575060c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9061046490879087906004016114b3565b602060405180830381865afa158015610481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a591906114c7565b949350505050565b6104c56000805160206116958339815191523361097a565b6104ea5760405162461bcd60e51b81526004016104e190611518565b60405180910390fd5b60cb5460005b8181101561058b5760cb818154811061050b5761050b611474565b600091825260209091200154604051633038c4b760e21b81526001600160a01b039091169063c0e312dc9061054690879087906004016114b3565b600060405180830381600087803b15801561056057600080fd5b505af1158015610574573d6000803e3d6000fd5b505050508080610583906114ff565b9150506104f0565b5060c954604051633cdd2cc360e01b81526001600160a01b0390911690633cdd2cc3906105be90869086906004016114b3565b600060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b50505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610625919061154f565b6040516020818303038152906040528051906020012081565b6106566000805160206116958339815191523361097a565b6106725760405162461bcd60e51b81526004016104e190611518565b60cb80546001810182556000919091527fa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fb0180546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152606560205260409020600101546106df81610d55565b6106e98383610d62565b505050565b6001600160a01b038116331461075e5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016104e1565b6107688282610d84565b5050565b60cb818154811061077c57600080fd5b6000918252602090912001546001600160a01b0316905081565b600054610100900460ff16158080156107b65750600054600160ff909116105b806107d05750303b1580156107d0575060005460ff166001145b6108335760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104e1565b6000805460ff191660011790558015610856576000805461ff0019166101001790555b6001600160a01b0382166108ac5760405162461bcd60e51b815260206004820152601c60248201527f4c696e6b657220616464726573732068617320746f206265207365740000000060448201526064016104e1565b6108b4610da6565b6108bf600033610e13565b6108d760008051602061169583398151915233610e13565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca80549285169290911691909117905560cc805460ff1916905580156106e9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60008281526097602052604081206109739083610e1d565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6109bd6000805160206116958339815191523361097a565b6109d95760405162461bcd60e51b81526004016104e190611518565b60005b60cb54811015610ab75760cb81815481106109f9576109f9611474565b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663cb703bff848460cb8581548110610a3a57610a3a611474565b6000918252602090912001546040516001600160e01b031960e086901b168152610a729392916001600160a01b03169060040161156b565b600060405180830381600087803b158015610a8c57600080fd5b505af1158015610aa0573d6000803e3d6000fd5b505050508080610aaf906114ff565b9150506109dc565b5060c95460405163f2f6360560e01b81526001600160a01b039091169063f2f6360590610aea90859085906004016114b3565b600060405180830381600087803b158015610b0457600080fd5b505af1158015610b18573d6000803e3d6000fd5b505050505050565b610b386000805160206116958339815191523361097a565b610b545760405162461bcd60e51b81526004016104e190611518565b60cb546000905b80821015610bac57826001600160a01b031660cb8381548110610b8057610b80611474565b6000918252602090912001546001600160a01b031614610bac5781610ba4816114ff565b925050610b5b565b808210156106e957610bbf600182611597565b821015610c3e5760cb610bd3600183611597565b81548110610be357610be3611474565b60009182526020909120015460cb80546001600160a01b039092169184908110610c0f57610c0f611474565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b60cb805480610c4f57610c4f6115aa565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b600081815260976020526040812061036790610e29565b600082815260656020526040902060010154610ca881610d55565b6106e98383610d84565b60cb5460009081905b80821015610d1657836001600160a01b031660cb8381548110610ce057610ce0611474565b6000918252602090912001546001600160a01b031603610d04575060019392505050565b81610d0e816114ff565b925050610cbb565b5060009392505050565b60006001600160e01b03198216637965db0b60e01b148061036757506301ffc9a760e01b6001600160e01b0319831614610367565b610d5f8133610e33565b50565b610d6c8282610e97565b60008281526097602052604090206106e99082610f1d565b610d8e8282610f32565b60008281526097602052604090206106e99082610f99565b600054610100900460ff16610e115760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104e1565b565b6107688282610d62565b60006109738383610fae565b6000610367825490565b610e3d828261097a565b61076857610e55816001600160a01b03166014610fd8565b610e60836020610fd8565b604051602001610e719291906115c0565b60408051601f198184030181529082905262461bcd60e51b82526104e19160040161141f565b610ea1828261097a565b6107685760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ed93390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610973836001600160a01b038416611174565b610f3c828261097a565b156107685760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610973836001600160a01b0384166111c3565b6000826000018281548110610fc557610fc5611474565b9060005260206000200154905092915050565b60606000610fe7836002611635565b610ff2906002611654565b67ffffffffffffffff81111561100a5761100a611667565b6040519080825280601f01601f191660200182016040528015611034576020820181803683370190505b509050600360fc1b8160008151811061104f5761104f611474565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061107e5761107e611474565b60200101906001600160f81b031916908160001a90535060006110a2846002611635565b6110ad906001611654565b90505b6001811115611125576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110e1576110e1611474565b1a60f81b8282815181106110f7576110f7611474565b60200101906001600160f81b031916908160001a90535060049490941c9361111e8161167d565b90506110b0565b5083156109735760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016104e1565b60008181526001830160205260408120546111bb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610367565b506000610367565b600081815260018301602052604081205480156112ac5760006111e7600183611597565b85549091506000906111fb90600190611597565b905081811461126057600086600001828154811061121b5761121b611474565b906000526020600020015490508087600001848154811061123e5761123e611474565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611271576112716115aa565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610367565b6000915050610367565b6000602082840312156112c857600080fd5b81356001600160e01b03198116811461097357600080fd5b600080602083850312156112f357600080fd5b823567ffffffffffffffff8082111561130b57600080fd5b818501915085601f83011261131f57600080fd5b81358181111561132e57600080fd5b86602082850101111561134057600080fd5b60209290920196919550909350505050565b60006020828403121561136457600080fd5b5035919050565b6001600160a01b0381168114610d5f57600080fd5b60006020828403121561139257600080fd5b81356109738161136b565b600080604083850312156113b057600080fd5b8235915060208301356113c28161136b565b809150509250929050565b600080604083850312156113e057600080fd5b82356113eb8161136b565b915060208301356113c28161136b565b60005b838110156114165781810151838201526020016113fe565b50506000910152565b602081526000825180602084015261143e8160408501602087016113fb565b601f01601f19169190910160400192915050565b6000806040838503121561146557600080fd5b50508035926020909101359150565b634e487b7160e01b600052603260045260246000fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006104a560208301848661148a565b6000602082840312156114d957600080fd5b8151801515811461097357600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611511576115116114e9565b5060010190565b6020808252601a908201527f5245474953545241525f524f4c45206973207265717569726564000000000000604082015260600190565b600082516115618184602087016113fb565b9190910192915050565b60408152600061157f60408301858761148a565b905060018060a01b0383166020830152949350505050565b81810381811115610367576103676114e9565b634e487b7160e01b600052603160045260246000fd5b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516115f88160178501602088016113fb565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516116298160288401602088016113fb565b01602801949350505050565b600081600019048311821515161561164f5761164f6114e9565b500290565b80820180821115610367576103676114e9565b634e487b7160e01b600052604160045260246000fd5b60008161168c5761168c6114e9565b50600019019056feedcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c309238a26469706673582212205c3ac6ab85f1fd2aa105748f1966cb6a752e6f4f19ee82ab54ceea3706fb192a64736f6c63430008100033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.meta.json b/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.meta.json new file mode 100644 index 000000000..de1c526d2 --- /dev/null +++ b/predeployed/src/ima_predeployed/artifacts/TokenManagerLinker.meta.json @@ -0,0 +1,410 @@ +{ + "name": "TokenManagerLinker", + "solcVersion": "0.8.16", + "solcLongVersion": "0.8.16+commit.07a7930e", + "input": { + "language": "Solidity", + "sources": { + "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageReceiver.sol\";\n\n\n// This contract runs on the main net and accepts deposits\ncontract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {\n\n address public erc721ContractOnMainnet;\n address public senderContractOnSchain;\n string public schainName;\n\n address public owner;\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Sender is not an owner\");\n _;\n }\n\n constructor(\n address newMessageProxyAddress,\n address newErc721Contract,\n string memory newSchainName\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721Contract != address(0), \"ERC721 contract has to be set\");\n erc721ContractOnMainnet = newErc721Contract;\n schainName = newSchainName;\n owner = msg.sender;\n }\n\n function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {\n require(newSenderContractOnSchain != address(0), \"Sender contract has to be set\");\n senderContractOnSchain = newSenderContractOnSchain;\n }\n\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n {\n require(schainHash == keccak256(abi.encodePacked(schainName)), \"Incorrect name of schain\");\n require(sender == senderContractOnSchain, \"Incorrect sender contract\");\n address to;\n uint256 tokenId;\n string memory tokenURI;\n (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));\n ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);\n require(\n ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),\n \"Token URI was not set\"\n );\n ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataMainnet {\n function setSenderContractOnSchain(address newSenderContractOnSchain) external;\n}" + }, + "contracts/schain/tokens/ERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol\";\n\n\n/**\n * @title ERC721OnChain\n * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.\n */\ncontract ERC721OnChain is\n AccessControlEnumerableUpgradeable,\n ERC721BurnableUpgradeable,\n ERC721URIStorageUpgradeable,\n IERC721OnChain\n{\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);\n ERC721BurnableUpgradeable.__ERC721Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Set URI of ERC721 token.\n * \n * Requirements:\n * \n * - token with {tokenId} must exist.\n * - sender must be the token owner or approved for the token.\n */\n function setTokenURI(uint256 tokenId, string calldata tokenUri)\n external\n override\n returns (bool)\n {\n require(_exists(tokenId), \"Token does not exists\");\n require(\n _isApprovedOrOwner(msg.sender, tokenId) ||\n hasRole(MINTER_ROLE, _msgSender()),\n \"Sender can not set token URI\"\n );\n _setTokenURI(tokenId, tokenUri);\n return true;\n }\n\n /**\n * @dev Mint token.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 tokenId)\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, tokenId);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Get token URI.\n */\n function tokenURI(\n uint256 tokenId\n )\n public\n view\n override (ERC721Upgradeable, ERC721URIStorageUpgradeable)\n returns (string memory) \n {\n return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n }\n\n // private\n\n /**\n * @dev Burn {tokenId}.\n */\n function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {\n ERC721URIStorageUpgradeable._burn(tokenId);\n }\n}\n" + }, + "contracts/extensions/interfaces/MessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\nimport \"./MessageProxyClient.sol\";\n\n\n// solhint-disable-next-line no-empty-blocks\nabstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\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), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {\n function __ERC721URIStorage_init() internal onlyInitializing {\n }\n\n function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n }\n using StringsUpgradeable for uint256;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\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\n return super.tokenURI(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), \"ERC721URIStorage: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev See {ERC721-_burn}. This override additionally checks to see if a\n * token-specific URI was set for the token, and if so, it deletes the token URI from\n * the storage mapping.\n */\n function _burn(uint256 tokenId) internal virtual override {\n super._burn(tokenId);\n\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721OnChain {\n function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);\n function mint(address account, uint256 tokenId) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\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 /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\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 _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token 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 _requireMinted(tokenId);\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 _setApprovalForAll(_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(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token 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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) 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 _owners[tokenId] != address(0);\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 address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\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(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\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 _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect 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 _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\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(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\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` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 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 ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 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 Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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`.\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(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\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 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(\n address from,\n address to,\n uint256 tokenId\n ) 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(\n address from,\n address to,\n uint256 tokenId\n ) 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 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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\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 IERC721ReceiverUpgradeable {\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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) 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(\n address target,\n bytes memory data,\n uint256 value\n ) 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(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) 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 (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(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal 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 /// @solidity memory-safe-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" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\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 /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\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 IERC165Upgradeable {\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" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\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 *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\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 // 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) {\n // 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 if (lastIndex != toDeleteIndex) {\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] = valueIndex; // Replace lastValue's index to valueIndex\n }\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 return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\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 * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\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 /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@skalenetwork/ima-interfaces/IMessageReceiver.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageReceiver.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageReceiver {\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external;\n}" + }, + "contracts/extensions/interfaces/MessageProxyClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../../MessageProxy.sol\";\n\nabstract contract MessageProxyClient {\n MessageProxy public messageProxy;\n\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n _;\n }\n\n constructor(address newMessageProxyAddress) {\n messageProxy = MessageProxy(newMessageProxyAddress);\n }\n}" + }, + "contracts/MessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/IGasReimbursable.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageProxy.sol\";\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\n/**\n * @title MessageProxy\n * @dev Abstract contract for MessageProxyForMainnet and MessageProxyForSchain.\n */\nabstract contract MessageProxy is AccessControlEnumerableUpgradeable, IMessageProxy {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n /**\n * @dev Structure that stores counters for outgoing and incoming messages.\n */\n struct ConnectedChainInfo {\n // message counters start with 0\n uint256 incomingMessageCounter;\n uint256 outgoingMessageCounter;\n bool inited;\n uint256 lastOutgoingMessageBlockId;\n }\n\n bytes32 public constant MAINNET_HASH = keccak256(abi.encodePacked(\"Mainnet\"));\n bytes32 public constant CHAIN_CONNECTOR_ROLE = keccak256(\"CHAIN_CONNECTOR_ROLE\");\n bytes32 public constant EXTRA_CONTRACT_REGISTRAR_ROLE = keccak256(\"EXTRA_CONTRACT_REGISTRAR_ROLE\");\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n uint256 public constant MESSAGES_LENGTH = 10;\n uint256 public constant REVERT_REASON_LENGTH = 64;\n\n // schainHash => ConnectedChainInfo\n mapping(bytes32 => ConnectedChainInfo) public connectedChains;\n // schainHash => contract address => allowed\n // solhint-disable-next-line private-vars-leading-underscore\n mapping(bytes32 => mapping(address => bool)) internal deprecatedRegistryContracts;\n\n uint256 public gasLimit;\n\n /**\n * @dev Emitted for every outgoing message to schain.\n */\n event OutgoingMessage(\n bytes32 indexed dstChainHash,\n uint256 indexed msgCounter,\n address indexed srcContract,\n address dstContract,\n bytes data\n );\n\n /**\n * @dev Emitted when function `postMessage` returns revert.\n * Used to prevent stuck loop inside function `postIncomingMessages`.\n */\n event PostMessageError(\n uint256 indexed msgCounter,\n bytes message\n );\n\n /**\n * @dev Emitted when gas limit per one call of `postMessage` was changed.\n */\n event GasLimitWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the version was updated\n */\n event VersionUpdated(string oldVersion, string newVersion);\n\n /**\n * @dev Emitted when extra contract was added.\n */\n event ExtraContractRegistered(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when extra contract was removed.\n */\n event ExtraContractRemoved(\n bytes32 indexed chainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when referenced to previous outgoing message.\n */\n event PreviousMessageReference (\n uint256 currentMessage,\n uint256 previousOutgoingMessageBlockId\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CHAIN_CONNECTOR_ROLE}.\n */\n modifier onlyChainConnector() {\n require(hasRole(CHAIN_CONNECTOR_ROLE, msg.sender), \"CHAIN_CONNECTOR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n */\n modifier onlyExtraContractRegistrar() {\n require(hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender), \"EXTRA_CONTRACT_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {CONSTANT_SETTER_ROLE}.\n */\n modifier onlyConstantSetter() {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n _;\n } \n\n /**\n * @dev Sets gasLimit to a new value.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CONSTANT_SETTER_ROLE.\n */\n function setNewGasLimit(uint256 newGasLimit) external override onlyConstantSetter {\n emit GasLimitWasChanged(gasLimit, newGasLimit);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Virtual function for `postIncomingMessages`.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n virtual\n override;\n\n /**\n * @dev Allows `msg.sender` to register extra contract for all schains\n * for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Passed address should be contract.\n * - Extra contract must not be registered.\n */\n function registerExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is already registered\");\n _getRegistryContracts()[bytes32(0)].add(extraContract);\n emit ExtraContractRegistered(bytes32(0), extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract for all schains.\n * Extra contract will no longer be able to send messages through MessageProxy.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n */\n function removeExtraContractForAll(address extraContract) external override onlyExtraContractRegistrar {\n require(_getRegistryContracts()[bytes32(0)].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[bytes32(0)].remove(extraContract);\n emit ExtraContractRemoved(bytes32(0), extraContract);\n }\n\n /**\n * @dev Should return length of contract registered by schainHash.\n */\n function getContractRegisteredLength(bytes32 schainHash) external view override returns (uint256) {\n return _getRegistryContracts()[schainHash].length();\n }\n\n /**\n * @dev Should return a range of contracts registered by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _getRegistryContracts()[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _getRegistryContracts()[schainHash].at(i);\n }\n }\n\n /**\n * @dev Returns number of outgoing messages.\n * \n * Requirements:\n * \n * - Target schain must be initialized.\n */\n function getOutgoingMessagesCounter(string calldata targetSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].outgoingMessageCounter;\n }\n\n\n /**\n * @dev Should return block number of the last message transferred to schain\n */\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view override returns (uint) {\n bytes32 dstChainHash = keccak256(abi.encodePacked(targetSchainName));\n require(connectedChains[dstChainHash].inited, \"Destination chain is not initialized\");\n return connectedChains[dstChainHash].lastOutgoingMessageBlockId;\n }\n\n /**\n * @dev Returns number of incoming messages.\n * \n * Requirements:\n * \n * - Source schain must be initialized.\n */\n function getIncomingMessagesCounter(string calldata fromSchainName)\n external\n view\n override\n returns (uint256)\n {\n bytes32 srcChainHash = keccak256(abi.encodePacked(fromSchainName));\n require(connectedChains[srcChainHash].inited, \"Source chain is not initialized\");\n return connectedChains[srcChainHash].incomingMessageCounter;\n }\n\n function initializeMessageProxy(uint newGasLimit) public initializer {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(CHAIN_CONNECTOR_ROLE, msg.sender);\n _setupRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender);\n _setupRole(CONSTANT_SETTER_ROLE, msg.sender);\n gasLimit = newGasLimit;\n }\n\n /**\n * @dev Posts message from this contract to `targetChainHash` MessageProxy contract.\n * This is called by a smart contract to make a cross-chain call.\n * \n * Emits an {OutgoingMessage} event.\n *\n * Requirements:\n * \n * - Target chain must be initialized.\n * - Target chain must be registered as external contract.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override\n virtual\n {\n require(connectedChains[targetChainHash].inited, \"Destination chain is not initialized\");\n _authorizeOutgoingMessageSender(targetChainHash);\n \n uint outgoingMessageCounter = connectedChains[targetChainHash].outgoingMessageCounter;\n emit OutgoingMessage(\n targetChainHash,\n outgoingMessageCounter,\n msg.sender,\n targetContract,\n data\n );\n emit PreviousMessageReference(\n outgoingMessageCounter,\n connectedChains[targetChainHash].lastOutgoingMessageBlockId\n );\n connectedChains[targetChainHash].outgoingMessageCounter++;\n connectedChains[targetChainHash].lastOutgoingMessageBlockId = block.number;\n }\n\n /**\n * @dev Allows CHAIN_CONNECTOR_ROLE to remove connected chain from this contract.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - `schainName` must be initialized.\n */\n function removeConnectedChain(string memory schainName) public virtual override onlyChainConnector {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(connectedChains[schainHash].inited, \"Chain is not initialized\");\n delete connectedChains[schainHash];\n } \n\n /**\n * @dev Checks whether chain is currently connected.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n virtual\n override\n returns (bool)\n {\n return connectedChains[keccak256(abi.encodePacked(schainName))].inited;\n }\n\n /**\n * @dev Checks whether contract is currently registered as extra contract.\n */\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n )\n public\n view\n override\n returns (bool)\n {\n return _getRegistryContracts()[schainHash].contains(contractAddress);\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Extra contract address must be contract.\n * - Extra contract must not be registered.\n * - Extra contract must not be registered for all chains.\n */\n function _registerExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n { \n require(extraContract.isContract(), \"Given address is not a contract\");\n require(!_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is already registered\");\n require(\n !_getRegistryContracts()[bytes32(0)].contains(extraContract),\n \"Extra contract is already registered for all chains\"\n );\n \n _getRegistryContracts()[chainHash].add(extraContract);\n emit ExtraContractRegistered(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n * \n * Requirements:\n * \n * - Extra contract must be registered.\n */\n function _removeExtraContract(\n bytes32 chainHash,\n address extraContract\n )\n internal\n {\n require(_getRegistryContracts()[chainHash].contains(extraContract), \"Extra contract is not registered\");\n _getRegistryContracts()[chainHash].remove(extraContract);\n emit ExtraContractRemoved(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to connect schain with MessageProxyOnMainnet for transferring messages.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted CHAIN_CONNECTOR_ROLE.\n * - SKALE chain must not be connected.\n */\n function _addConnectedChain(bytes32 schainHash) internal onlyChainConnector {\n require(!connectedChains[schainHash].inited,\"Chain is already connected\");\n connectedChains[schainHash] = ConnectedChainInfo({\n incomingMessageCounter: 0,\n outgoingMessageCounter: 0,\n inited: true,\n lastOutgoingMessageBlockId: 0\n });\n }\n\n /**\n * @dev Allows MessageProxy to send messages from schain to mainnet.\n * Destination contract must implement `postMessage` method.\n */\n function _callReceiverContract(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n {\n if (!message.destinationContract.isContract()) {\n emit PostMessageError(\n counter,\n \"Destination contract is not a contract\"\n );\n return;\n }\n try IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) {\n return;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n }\n }\n\n /**\n * @dev Returns receiver of message.\n */\n function _getGasPayer(\n bytes32 schainHash,\n Message calldata message,\n uint counter\n )\n internal\n returns (address)\n {\n try IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(\n schainHash,\n message.sender,\n message.data\n ) returns (address receiver) {\n return receiver;\n } catch Error(string memory reason) {\n emit PostMessageError(\n counter,\n _getSlice(bytes(reason), REVERT_REASON_LENGTH)\n );\n return address(0);\n } catch Panic(uint errorCode) {\n emit PostMessageError(\n counter,\n abi.encodePacked(errorCode)\n );\n return address(0);\n } catch (bytes memory revertData) {\n emit PostMessageError(\n counter,\n _getSlice(revertData, REVERT_REASON_LENGTH)\n );\n return address(0);\n }\n }\n\n /**\n * @dev Checks whether msg.sender is registered as custom extra contract.\n */\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view virtual {\n require(\n isContractRegistered(bytes32(0), msg.sender) || isContractRegistered(targetChainHash, msg.sender),\n \"Sender contract is not registered\"\n ); \n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n virtual\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage);\n\n /**\n * @dev Returns hash of message array.\n */\n function _hashedArray(\n Message[] calldata messages,\n uint256 startingCounter,\n string calldata fromChainName\n )\n internal\n pure\n returns (bytes32)\n {\n bytes32 sourceHash = keccak256(abi.encodePacked(fromChainName));\n bytes32 hash = keccak256(abi.encodePacked(sourceHash, bytes32(startingCounter)));\n for (uint256 i = 0; i < messages.length; i++) {\n hash = keccak256(\n abi.encodePacked(\n abi.encode(\n hash,\n messages[i].sender,\n messages[i].destinationContract\n ),\n messages[i].data\n )\n );\n }\n return hash;\n }\n\n function _getSlice(bytes memory text, uint end) private pure returns (bytes memory) {\n uint slicedEnd = end < text.length ? end : text.length;\n bytes memory sliced = new bytes(slicedEnd);\n for(uint i = 0; i < slicedEnd; i++){\n sliced[i] = text[i];\n }\n return sliced; \n }\n}\n" + }, + "@skalenetwork/ima-interfaces/IGasReimbursable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IGasReimbursable.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageReceiver.sol\";\n\n\ninterface IGasReimbursable is IMessageReceiver {\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/IMessageProxy.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxy.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IMessageProxy {\n\n /**\n * @dev Structure that describes message. Should contain sender of message,\n * destination contract on schain that will receiver message,\n * data that contains all needed info about token or ETH.\n */\n struct Message {\n address sender;\n address destinationContract;\n bytes data;\n }\n\n /**\n * @dev Structure that contains fields for bls signature.\n */\n struct Signature {\n uint256[2] blsSignature;\n uint256 hashA;\n uint256 hashB;\n uint256 counter;\n }\n\n function addConnectedChain(string calldata schainName) external;\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n ) external;\n function setNewGasLimit(uint256 newGasLimit) external;\n function registerExtraContractForAll(address extraContract) external;\n function removeExtraContractForAll(address extraContract) external; \n function removeConnectedChain(string memory schainName) external;\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n ) external;\n function registerExtraContract(string memory chainName, address extraContract) external;\n function removeExtraContract(string memory schainName, address extraContract) external;\n function setVersion(string calldata newVersion) external;\n function isContractRegistered(\n bytes32 schainHash,\n address contractAddress\n ) external view returns (bool);\n function getContractRegisteredLength(bytes32 schainHash) external view returns (uint256);\n function getContractRegisteredRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getOutgoingMessagesCounter(string calldata targetSchainName) external view returns (uint256);\n function getIncomingMessagesCounter(string calldata fromSchainName) external view returns (uint256);\n function isConnectedChain(string memory schainName) external view returns (bool);\n function getLastOutgoingMessageBlockId(string memory targetSchainName) external view returns (uint);\n}" + }, + "contracts/extensions/interfaces/MessageSender.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageSender.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyClient.sol\";\n\nabstract contract MessageSender is MessageProxyClient {\n\n function _sendMessage(\n string memory targetChainName,\n address targetContract,\n bytes memory data\n ) internal {\n messageProxy.postOutgoingMessage(keccak256(abi.encodePacked(targetChainName)), targetContract, data);\n }\n}" + }, + "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol\";\n\nimport \"../schain/tokens/ERC721OnChain.sol\";\nimport \"./interfaces/MessageSender.sol\";\n\n\n/**\n * @title Token Manager\n * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs\n * TokenFactory to create clones.\n When a user exits a SKALE chain, TokenFactory\n * burns tokens.\n */\ncontract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {\n\n address public erc721ContractOnSchain;\n address public receiverContractOnMainnet;\n\n constructor(\n address newMessageProxyAddress,\n address newErc721ContractOnSchain,\n address newReceiverContractOnMainnet\n )\n MessageProxyClient(newMessageProxyAddress)\n {\n require(newErc721ContractOnSchain != address(0), \"ERC721 contract has to be set\");\n require(newReceiverContractOnMainnet != address(0), \"Receiver contract has to be set\");\n erc721ContractOnSchain = newErc721ContractOnSchain;\n receiverContractOnMainnet = newReceiverContractOnMainnet;\n }\n\n function sendTokenToMainnet(address receiver, uint256 tokenId) external override {\n require(\n ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),\n \"Not allowed ERC721 Token\"\n );\n ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);\n string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);\n ERC721OnChain(erc721ContractOnSchain).burn(tokenId);\n bytes memory data = encodeParams(receiver, tokenId, tokenURI);\n _sendMessage(\"Mainnet\", receiverContractOnMainnet, data);\n }\n\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n public\n pure\n override\n returns (bytes memory data)\n {\n data = abi.encode(receiver, tokenId, tokenURI);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC721ReferenceMintAndMetadataSchain {\n function sendTokenToMainnet(address receiver, uint256 tokenId) external;\n function encodeParams(\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n )\n external\n pure\n returns (bytes memory data);\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC721OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC721\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC721 on Mainnet => ERC721 on Schain\n mapping(address => ERC721OnChain) public deprecatedClonesErc721;\n\n // address clone on schain => added or not\n mapping(ERC721OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC721OnChain)) public clonesErc721;\n\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when schain owner register new ERC721 clone.\n */\n event ERC721TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.\n */\n event ERC721TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC721TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc721OnMainChain,\n address indexed erc721OnSchain,\n uint256 tokenId\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC721(\n address contractOnMainnet,\n uint256 tokenId\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC721 token clone in the token manager.\n */\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainChain,\n address erc721OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc721OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc721[targetChainHash][erc721OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC721OnChain(erc721OnSchain)], \"Clone was already added\");\n clonesErc721[targetChainHash][erc721OnMainChain] = ERC721OnChain(erc721OnSchain);\n addedClones[ERC721OnChain(erc721OnSchain)] = true;\n emit ERC721TokenAdded(targetChainHash, erc721OnMainChain, erc721OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n } \n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal virtual returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721) {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n receiver = message.receiver;\n token = message.token;\n tokenId = message.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721AndTokenInfoMessage memory message =\n Messages.decodeTransferErc721AndTokenInfoMessage(data);\n receiver = message.baseErc721transfer.receiver;\n token = message.baseErc721transfer.token;\n tokenId = message.baseErc721transfer.tokenId;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC721[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == chainHash, \"Token was already transferred from chain\");\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(bytes32 chainHash, address erc721OnMainChain) internal {\n require(erc721OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[chainHash].contains(erc721OnMainChain), \"ERC721 Token was already added\");\n _schainToERC721[chainHash].add(erc721OnMainChain);\n emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc721Token, uint256 tokenId) internal {\n require(transferredAmount[erc721Token][tokenId] == bytes32(0), \"Token was already transferred to chain\");\n transferredAmount[erc721Token][tokenId] = chainHash;\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n function _isERC721AddedToSchain(bytes32 chainHash, address erc721OnMainChain) internal view returns (bool) {\n return _schainToERC721[chainHash].contains(erc721OnMainChain);\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC721 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC721 is ITokenContractManager {\n function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;\n function transferToSchainERC721(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 tokenId\n ) external;\n function addERC721TokenByOwner(\n string calldata targetChainName,\n address erc721OnMainnet,\n address erc721OnSchain\n ) external;\n}" + }, + "contracts/Messages.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Messages.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\n/**\n * @title Messages\n * @dev Library for encoding and decoding messages\n * for transferring from Mainnet to Schain and vice versa.\n */\nlibrary Messages {\n\n /**\n * @dev Enumerator that describes all supported message types.\n */\n enum MessageType {\n EMPTY,\n TRANSFER_ETH,\n TRANSFER_ERC20,\n TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n TRANSFER_ERC20_AND_TOKEN_INFO,\n TRANSFER_ERC721,\n TRANSFER_ERC721_AND_TOKEN_INFO,\n USER_STATUS,\n INTERCHAIN_CONNECTION,\n TRANSFER_ERC1155,\n TRANSFER_ERC1155_AND_TOKEN_INFO,\n TRANSFER_ERC1155_BATCH,\n TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n TRANSFER_ERC721_WITH_METADATA,\n TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO\n }\n\n /**\n * @dev Structure for base message.\n */\n struct BaseMessage {\n MessageType messageType;\n }\n\n /**\n * @dev Structure for describing ETH.\n */\n struct TransferEthMessage {\n BaseMessage message;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for user status.\n */\n struct UserStatusMessage {\n BaseMessage message;\n address receiver;\n bool isActive;\n }\n\n /**\n * @dev Structure for describing ERC20 token.\n */\n struct TransferErc20Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing additional data for ERC20 token.\n */\n struct Erc20TokenInfo {\n string name;\n uint8 decimals;\n string symbol;\n }\n\n /**\n * @dev Structure for describing ERC20 with token supply.\n */\n struct TransferErc20AndTotalSupplyMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct TransferErc20AndTokenInfoMessage {\n TransferErc20Message baseErc20transfer;\n uint256 totalSupply;\n Erc20TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing base ERC721.\n */\n struct TransferErc721Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 tokenId;\n }\n\n /**\n * @dev Structure for describing base ERC721 with metadata.\n */\n struct TransferErc721MessageWithMetadata {\n TransferErc721Message erc721message;\n string tokenURI;\n }\n\n /**\n * @dev Structure for describing ERC20 with token info.\n */\n struct Erc721TokenInfo {\n string name;\n string symbol;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token.\n */\n struct TransferErc721AndTokenInfoMessage {\n TransferErc721Message baseErc721transfer;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing additional data for ERC721 token with metadata.\n */\n struct TransferErc721WithMetadataAndTokenInfoMessage {\n TransferErc721MessageWithMetadata baseErc721transferWithMetadata;\n Erc721TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct InterchainConnectionMessage {\n BaseMessage message;\n bool isAllowed;\n }\n\n /**\n * @dev Structure for describing whether interchain connection is allowed.\n */\n struct TransferErc1155Message {\n BaseMessage message;\n address token;\n address receiver;\n uint256 id;\n uint256 amount;\n }\n\n /**\n * @dev Structure for describing ERC1155 token in batches.\n */\n struct TransferErc1155BatchMessage {\n BaseMessage message;\n address token;\n address receiver;\n uint256[] ids;\n uint256[] amounts;\n }\n\n /**\n * @dev Structure for describing ERC1155 token info.\n */\n struct Erc1155TokenInfo {\n string uri;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token with info.\n */\n struct TransferErc1155AndTokenInfoMessage {\n TransferErc1155Message baseErc1155transfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n /**\n * @dev Structure for describing message for transferring ERC1155 token in batches with info.\n */\n struct TransferErc1155BatchAndTokenInfoMessage {\n TransferErc1155BatchMessage baseErc1155Batchtransfer;\n Erc1155TokenInfo tokenInfo;\n }\n\n\n /**\n * @dev Returns type of message for encoded data.\n */\n function getMessageType(bytes calldata data) internal pure returns (MessageType) {\n uint256 firstWord = abi.decode(data, (uint256));\n if (firstWord % 32 == 0) {\n return getMessageType(data[firstWord:]);\n } else {\n return abi.decode(data, (Messages.MessageType));\n }\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferEthMessage(address receiver, uint256 amount) internal pure returns (bytes memory) {\n TransferEthMessage memory message = TransferEthMessage(\n BaseMessage(MessageType.TRANSFER_ETH),\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ETH. Returns structure `TransferEthMessage`.\n */\n function decodeTransferEthMessage(\n bytes calldata data\n ) internal pure returns (TransferEthMessage memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ETH, \"Message type is not ETH transfer\");\n return abi.decode(data, (TransferEthMessage));\n }\n\n /**\n * @dev Encodes message for transferring ETH. Returns encoded message.\n */\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc20Message memory message = TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20),\n token,\n receiver,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with total supply. Returns encoded message.\n */\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) internal pure returns (bytes memory) {\n TransferErc20AndTotalSupplyMessage memory message = TransferErc20AndTotalSupplyMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY),\n token,\n receiver,\n amount\n ),\n totalSupply\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20. Returns structure `TransferErc20Message`.\n */\n function decodeTransferErc20Message(\n bytes calldata data\n ) internal pure returns (TransferErc20Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC20, \"Message type is not ERC20 transfer\");\n return abi.decode(data, (TransferErc20Message));\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with total supply. \n * Returns structure `TransferErc20AndTotalSupplyMessage`.\n */\n function decodeTransferErc20AndTotalSupplyMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTotalSupplyMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY,\n \"Message type is not ERC20 transfer and total supply\"\n );\n return abi.decode(data, (TransferErc20AndTotalSupplyMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC20 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Erc20TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc20AndTokenInfoMessage memory message = TransferErc20AndTokenInfoMessage(\n TransferErc20Message(\n BaseMessage(MessageType.TRANSFER_ERC20_AND_TOKEN_INFO),\n token,\n receiver,\n amount\n ),\n totalSupply,\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC20 with token info. \n * Returns structure `TransferErc20AndTokenInfoMessage`.\n */\n function decodeTransferErc20AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc20AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC20_AND_TOKEN_INFO,\n \"Message type is not ERC20 transfer with token info\"\n );\n return abi.decode(data, (TransferErc20AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) internal pure returns (bytes memory) {\n TransferErc721Message memory message = TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721),\n token,\n receiver,\n tokenId\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721Message`.\n */\n function decodeTransferErc721Message(\n bytes calldata data\n ) internal pure returns (TransferErc721Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC721, \"Message type is not ERC721 transfer\");\n return abi.decode(data, (TransferErc721Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721AndTokenInfoMessage memory message = TransferErc721AndTokenInfoMessage(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721AndTokenInfoMessage`.\n */\n function decodeTransferErc721AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC721. \n * Returns encoded message.\n */\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) internal pure returns (bytes memory) {\n TransferErc721MessageWithMetadata memory message = TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721. \n * Returns structure `TransferErc721MessageWithMetadata`.\n */\n function decodeTransferErc721MessageWithMetadata(\n bytes calldata data\n ) internal pure returns (TransferErc721MessageWithMetadata memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA,\n \"Message type is not ERC721 transfer\"\n );\n return abi.decode(data, (TransferErc721MessageWithMetadata));\n }\n\n /**\n * @dev Encodes message for transferring ERC721 with token info. \n * Returns encoded message.\n */\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Erc721TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc721WithMetadataAndTokenInfoMessage memory message = TransferErc721WithMetadataAndTokenInfoMessage(\n TransferErc721MessageWithMetadata(\n TransferErc721Message(\n BaseMessage(MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO),\n token,\n receiver,\n tokenId\n ),\n tokenURI\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC721 with token info. \n * Returns structure `TransferErc721WithMetadataAndTokenInfoMessage`.\n */\n function decodeTransferErc721WithMetadataAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc721WithMetadataAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO,\n \"Message type is not ERC721 transfer with token info\"\n );\n return abi.decode(data, (TransferErc721WithMetadataAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for activating user on schain. \n * Returns encoded message.\n */\n function encodeActivateUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, true);\n }\n\n /**\n * @dev Encodes message for locking user on schain. \n * Returns encoded message.\n */\n function encodeLockUserMessage(address receiver) internal pure returns (bytes memory){\n return _encodeUserStatusMessage(receiver, false);\n }\n\n /**\n * @dev Decodes message for user status. \n * Returns structure UserStatusMessage.\n */\n function decodeUserStatusMessage(bytes calldata data) internal pure returns (UserStatusMessage memory) {\n require(getMessageType(data) == MessageType.USER_STATUS, \"Message type is not User Status\");\n return abi.decode(data, (UserStatusMessage));\n }\n\n\n /**\n * @dev Encodes message for allowing interchain connection.\n * Returns encoded message.\n */\n function encodeInterchainConnectionMessage(bool isAllowed) internal pure returns (bytes memory) {\n InterchainConnectionMessage memory message = InterchainConnectionMessage(\n BaseMessage(MessageType.INTERCHAIN_CONNECTION),\n isAllowed\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for allowing interchain connection.\n * Returns structure `InterchainConnectionMessage`.\n */\n function decodeInterchainConnectionMessage(bytes calldata data)\n internal\n pure\n returns (InterchainConnectionMessage memory)\n {\n require(getMessageType(data) == MessageType.INTERCHAIN_CONNECTION, \"Message type is not Interchain connection\");\n return abi.decode(data, (InterchainConnectionMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token.\n * Returns encoded message.\n */\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) internal pure returns (bytes memory) {\n TransferErc1155Message memory message = TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155),\n token,\n receiver,\n id,\n amount\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token.\n * Returns structure `TransferErc1155Message`.\n */\n function decodeTransferErc1155Message(\n bytes calldata data\n ) internal pure returns (TransferErc1155Message memory) {\n require(getMessageType(data) == MessageType.TRANSFER_ERC1155, \"Message type is not ERC1155 transfer\");\n return abi.decode(data, (TransferErc1155Message));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155AndTokenInfoMessage memory message = TransferErc1155AndTokenInfoMessage(\n TransferErc1155Message(\n BaseMessage(MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO),\n token,\n receiver,\n id,\n amount\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 with token info.\n * Returns structure `TransferErc1155AndTokenInfoMessage`.\n */\n function decodeTransferErc1155AndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155AndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO,\n \"Message type is not ERC1155AndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155AndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchMessage memory message = TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH),\n token,\n receiver,\n ids,\n amounts\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches.\n * Returns structure `TransferErc1155BatchMessage`.\n */\n function decodeTransferErc1155BatchMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH,\n \"Message type is not ERC1155Batch transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchMessage));\n }\n\n /**\n * @dev Encodes message for transferring ERC1155 token in batches with token info.\n * Returns encoded message.\n */\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Erc1155TokenInfo memory tokenInfo\n ) internal pure returns (bytes memory) {\n TransferErc1155BatchAndTokenInfoMessage memory message = TransferErc1155BatchAndTokenInfoMessage(\n TransferErc1155BatchMessage(\n BaseMessage(MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO),\n token,\n receiver,\n ids,\n amounts\n ),\n tokenInfo\n );\n return abi.encode(message);\n }\n\n /**\n * @dev Decodes message for transferring ERC1155 token in batches with token info.\n * Returns structure `TransferErc1155BatchAndTokenInfoMessage`.\n */\n function decodeTransferErc1155BatchAndTokenInfoMessage(\n bytes calldata data\n ) internal pure returns (TransferErc1155BatchAndTokenInfoMessage memory) {\n require(\n getMessageType(data) == MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO,\n \"Message type is not ERC1155BatchAndTokenInfo transfer\"\n );\n return abi.decode(data, (TransferErc1155BatchAndTokenInfoMessage));\n }\n\n /**\n * @dev Encodes message for transferring user status on schain.\n * Returns encoded message.\n */\n function _encodeUserStatusMessage(address receiver, bool isActive) private pure returns (bytes memory) {\n UserStatusMessage memory message = UserStatusMessage(\n BaseMessage(MessageType.USER_STATUS),\n receiver,\n isActive\n );\n return abi.encode(message);\n }\n\n}" + }, + "contracts/schain/TokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManager.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"./MessageProxyForSchain.sol\";\nimport \"./TokenManagerLinker.sol\";\nimport \"./CommunityLocker.sol\";\n\n\n/**\n * @title TokenManager\n * @dev Base contract for all token managers.\n * \n * Runs on SKALE Chains, accepts messages from mainnet, creates clones of tokens.\n * TokenManager mints tokens when user locks tokens on mainnet and burn them when user exits.\n */\nabstract contract TokenManager is AccessControlEnumerableUpgradeable, ITokenManager {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows turning on and turning off of automatic token clones deployment.\n */\n bytes32 public constant AUTOMATIC_DEPLOY_ROLE = keccak256(\"AUTOMATIC_DEPLOY_ROLE\");\n\n /**\n * @dev id of a role that allows to register deployed token clone.\n */\n bytes32 public constant TOKEN_REGISTRAR_ROLE = keccak256(\"TOKEN_REGISTRAR_ROLE\");\n \n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityLocker.\n */\n ICommunityLocker public communityLocker;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Address of corresponding deposit box on mainnet.\n */\n address public depositBox;\n\n /**\n * @dev Show if automatic deploy of token clones are allowed.\n */\n bool public automaticDeploy;\n\n /**\n * @dev Addresses of corresponding token manager on other SKALE chains.\n */\n // schainHash => TokenManager\n mapping(bytes32 => address) public tokenManagers; \n\n /**\n * @dev Emitted when deposit box address was changed.\n */\n event DepositBoxWasChanged(\n address oldValue,\n address newValue\n );\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n modifier onlyAutomaticDeploy() {\n require(hasRole(AUTOMATIC_DEPLOY_ROLE, msg.sender), \"AUTOMATIC_DEPLOY_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {TOKEN_REGISTRAR_ROLE}.\n */\n modifier onlyTokenRegistrar() {\n require(hasRole(TOKEN_REGISTRAR_ROLE, msg.sender), \"TOKEN_REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if caller is {MessageProxy}.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * a message does not aim mainnet, target SKALE chain has token manager and receiver is set.\n */\n modifier rightTransaction(string memory targetSchainName, address to) {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n require(\n targetSchainHash != MAINNET_HASH,\n \"This function is not for transferring to Mainnet\"\n );\n require(to != address(0), \"Incorrect receiver address\");\n require(tokenManagers[targetSchainHash] != address(0), \"Incorrect Token Manager address\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only if\n * sender is deposit box on mainnet or token manager on other SKALE chain.\n */\n modifier checkReceiverChain(bytes32 fromChainHash, address sender) {\n require(fromChainHash != schainHash && _checkSender(fromChainHash, sender), \"Receiver chain is incorrect\");\n _;\n }\n\n\n /**\n * @dev Turn on automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function enableAutomaticDeploy() external override onlyAutomaticDeploy {\n automaticDeploy = true;\n }\n\n /**\n * @dev Turn off automatic deploy on schain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {AUTOMATIC_DEPLOY_ROLE}.\n */\n function disableAutomaticDeploy() external onlyAutomaticDeploy {\n automaticDeploy = false;\n }\n\n /**\n * @dev Adds a TokenManager on SKALE chain to this TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must not already be added.\n * - TokenManager address must be non-zero.\n */\n function addTokenManager(string calldata schainName, address newTokenManager) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] == address(0), \"Token Manager is already set\");\n require(newTokenManager != address(0), \"Incorrect Token Manager address\");\n tokenManagers[newSchainHash] = newTokenManager;\n }\n\n /**\n * @dev Remove a TokenManager on SKALE chain from TokenManager.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner or {TokenManagerLinker} contract.\n * - SKALE chain must already be set.\n */\n function removeTokenManager(string calldata schainName) external override {\n require(\n msg.sender == address(tokenManagerLinker) ||\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\"\n );\n bytes32 newSchainHash = keccak256(abi.encodePacked(schainName));\n require(tokenManagers[newSchainHash] != address(0), \"Token Manager is not set\");\n delete tokenManagers[newSchainHash];\n }\n\n /**\n * @dev Change Deposit Box address\n * This function should be executed only in emergency.\n *\n * Requirements:\n *\n * - `msg.sender` must be contract owner.\n * - {newDepositBox} must be set.\n */\n function changeDepositBoxAddress(address newDepositBox) external {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n emit DepositBoxWasChanged(depositBox, newDepositBox);\n depositBox = newDepositBox;\n }\n\n /**\n * @dev Checks whether TokenManager is connected to a {schainName} SKALE chain TokenManager.\n */\n function hasTokenManager(string calldata schainName) external view override returns (bool) {\n return tokenManagers[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initializeTokenManager(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n public\n virtual\n initializer\n {\n require(newDepositBox != address(0), \"DepositBox address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(AUTOMATIC_DEPLOY_ROLE, msg.sender);\n _setupRole(TOKEN_REGISTRAR_ROLE, msg.sender);\n\n schainHash = keccak256(abi.encodePacked(newSchainName));\n messageProxy = newMessageProxy;\n tokenManagerLinker = newIMALinker;\n communityLocker = newCommunityLocker; \n depositBox = newDepositBox;\n\n emit DepositBoxWasChanged(address(0), newDepositBox);\n }\n\n /**\n * @dev Checks whether sender contract is DepositBox or TokenManager depending on chainHash.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view virtual returns (bool) {\n return fromChainHash == MAINNET_HASH ? sender == depositBox : sender == tokenManagers[fromChainHash];\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\ninterface ITokenContractManager is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n ) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityLocker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManagerLinker.sol\";\n\n\ninterface ICommunityLocker is IMessageReceiver {\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n ) external;\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver) external;\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external;\n function setGasPrice(uint gasPrice, uint timestamp, IMessageProxyForSchain.Signature memory signature) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./IKeyStorage.sol\";\n\ninterface IMessageProxyForSchain is IMessageProxy {\n struct OutgoingMessageData {\n bytes32 dstChainHash; // destination chain\n uint256 msgCounter; // message counter\n address srcContract; // origin\n address dstContract; // receiver\n bytes data; // payload\n }\n\n function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;\n function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);\n function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);\n function messageInProgress() external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManager - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageReceiver.sol\";\n\n\ninterface ITokenManager is IMessageReceiver {\n function enableAutomaticDeploy() external;\n function addTokenManager(string calldata schainName, address newTokenManager) external;\n function removeTokenManager(string calldata schainName) external;\n function hasTokenManager(string calldata schainName) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerLinker - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./IMessageProxyForSchain.sol\";\nimport \"./ITokenManager.sol\";\n\n\ninterface ITokenManagerLinker {\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;\n function registerTokenManager(ITokenManager newTokenManager) external;\n function removeTokenManager(ITokenManager tokenManagerAddress) external;\n function connectSchain(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function hasTokenManager(ITokenManager tokenManager) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IKeyStorage.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./bls/IFieldOperations.sol\";\n\n\ninterface IKeyStorage {\n function initialize() external;\n function getBlsCommonPublicKey() external view returns (IFieldOperations.G2Point memory);\n}" + }, + "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IFieldOperations.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IFieldOperations {\n\n /**\n * @dev Structure that represents the field element { a + ib }\n */\n struct Fp2Point {\n uint a;\n uint b;\n }\n\n /**\n * @dev Structure that represents an element of G2\n */\n struct G2Point {\n Fp2Point x;\n Fp2Point y;\n }\n}" + }, + "contracts/schain/MessageProxyForSchain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\nimport \"../MessageProxy.sol\";\nimport \"./bls/SkaleVerifier.sol\";\n\n\n/**\n * @title MessageProxyForSchain\n * @dev Entry point for messages that come from mainnet or other SKALE chains\n * and contract that emits messages for mainnet or other SKALE chains.\n * \n * Messages are submitted by IMA-agent and secured with threshold signature.\n * \n * IMA-agent monitors events of {MessageProxyForSchain} and sends messages to other chains.\n\n * NOTE: 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 5 minutes\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\ncontract MessageProxyForSchain is MessageProxy, IMessageProxyForSchain {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n IEtherbaseUpgradeable public constant ETHERBASE = IEtherbaseUpgradeable(\n payable(0xd2bA3e0000000000000000000000000000000000)\n );\n uint public constant MINIMUM_BALANCE = 1 ether;\n\n /**\n * @dev Structure that contains information about outgoing message.\n */\n\n /**\n * @dev Address of {KeyStorage}.\n */\n IKeyStorage public keyStorage;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n /**\n * @dev Hashed of meta information of outgoing messages.\n */\n // schainHash => message_id => MessageData\n mapping(bytes32 => mapping(uint256 => bytes32)) private _outgoingMessageDataHash;\n\n /**\n * @dev First unprocessed outgoing message.\n */\n // schainHash => head of unprocessed messages\n mapping(bytes32 => uint) private _idxHead;\n\n /**\n * @dev Last unprocessed outgoing message.\n */\n // schainHash => tail of unprocessed messages\n mapping(bytes32 => uint) private _idxTail;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n\n string public version;\n bool public override messageInProgress;\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Allows MessageProxy to register extra contract for being able to transfer messages from custom contracts.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function registerExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _registerExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Allows MessageProxy to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from chain to chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {EXTRA_CONTRACT_REGISTRAR_ROLE}.\n * - Destination chain hash cannot be equal to itself\n */\n function removeExtraContract(\n string memory chainName,\n address extraContract\n )\n external\n override\n onlyExtraContractRegistrar\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Destination chain hash cannot be equal to itself\");\n _removeExtraContract(chainHash, extraContract);\n }\n\n /**\n * @dev Link external chain.\n *\n * NOTE: Mainnet is linked automatically.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from the current.\n */\n function addConnectedChain(string calldata chainName) external override {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Schain cannot connect itself\");\n _addConnectedChain(chainHash);\n } \n\n /**\n * @dev Entry point for incoming messages.\n * This function is called by IMA-agent to deliver incoming messages from external chains.\n * \n * Requirements:\n * \n * - Origin chain has to be registered.\n * - Amount of messages must be no more than {MESSAGES_LENGTH}.\n * - Messages batch has to be signed with threshold signature.\n * by super majority of current SKALE chain nodes.\n * - All previous messages must be already delivered.\n */\n function postIncomingMessages(\n string calldata fromChainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata signature \n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n {\n bytes32 fromChainHash = keccak256(abi.encodePacked(fromChainName));\n require(connectedChains[fromChainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(_verifyMessages(\n _hashedArray(messages, startingCounter, fromChainName), signature),\n \"Signature is not verified\");\n require(\n startingCounter == connectedChains[fromChainHash].incomingMessageCounter,\n \"Starting counter is not qual to incoming message counter\");\n connectedChains[fromChainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n _callReceiverContract(fromChainHash, messages[i], startingCounter + 1);\n }\n _topUpBalance();\n }\n\n /**\n * @dev Sets new version of contracts on schain\n * \n * Requirements:\n * \n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Verify if the message metadata is valid.\n */\n function verifyOutgoingMessageData(\n OutgoingMessageData memory message\n )\n external\n view\n override\n returns (bool isValidMessage)\n {\n bytes32 messageDataHash = _outgoingMessageDataHash[message.dstChainHash][message.msgCounter];\n if (messageDataHash == _hashOfMessage(message))\n isValidMessage = true;\n }\n\n /**\n * @dev Verify signature of hashed message\n */\n function verifySignature(bytes32 hashedMessage, MessageProxyForSchain.Signature calldata signature)\n external\n view\n override\n returns (bool)\n {\n return _verifyMessages(hashedMessage, signature);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(IKeyStorage blsKeyStorage, string memory schainName)\n public\n override\n virtual\n initializer\n {\n MessageProxy.initializeMessageProxy(3e6);\n keyStorage = blsKeyStorage;\n connectedChains[\n MAINNET_HASH\n ] = ConnectedChainInfo(\n 0,\n 0,\n true,\n 0\n );\n\t schainHash = keccak256(abi.encodePacked(schainName));\n\n // In predeployed mode all token managers and community locker\n // will be added to registryContracts\n }\n\n /**\n * @dev Unlink external SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {CHAIN_CONNECTOR_ROLE}.\n * - Target chain must be different from Mainnet.\n */\n function removeConnectedChain(\n string memory chainName\n )\n public\n override(IMessageProxy, MessageProxy)\n onlyChainConnector\n {\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != MAINNET_HASH, \"Mainnet cannot be removed\");\n super.removeConnectedChain(chainName);\n }\n\n /**\n * @dev This function is called by a smart contract\n * that wants to make a cross-chain call.\n * \n * Requirements:\n * \n * - Destination chain has to be registered.\n * - Sender contract has to be registered.\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n\n OutgoingMessageData memory outgoingMessageData = OutgoingMessageData(\n targetChainHash,\n connectedChains[targetChainHash].outgoingMessageCounter - 1,\n msg.sender,\n targetContract,\n data\n );\n\n bytes32 dstChainHash = outgoingMessageData.dstChainHash;\n _outgoingMessageDataHash[dstChainHash][_idxTail[dstChainHash]] = _hashOfMessage(outgoingMessageData);\n _idxTail[dstChainHash] += 1;\n }\n\n // private\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n * Returns true if signature is valid.\n */\n function _verifyMessages(\n bytes32 hashedMessages,\n MessageProxyForSchain.Signature calldata signature\n )\n internal\n view\n virtual\n returns (bool)\n {\n return SkaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signature.blsSignature[0],\n b: signature.blsSignature[1]\n }),\n hashedMessages,\n signature.counter,\n signature.hashA,\n signature.hashB,\n keyStorage.getBlsCommonPublicKey()\n );\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n /**\n * @dev Returns Etherbase contract\n */\n function _getEtherbase() internal view virtual returns (IEtherbaseUpgradeable) {\n return ETHERBASE;\n }\n\n /**\n * @dev Move skETH from Etherbase if the balance is too low\n */\n function _topUpBalance() private {\n uint balance = msg.sender.balance + gasleft() * tx.gasprice;\n IEtherbaseUpgradeable etherbase = _getEtherbase();\n if (address(etherbase).isContract()\n && etherbase.hasRole(etherbase.ETHER_MANAGER_ROLE(), address(this)) \n && balance < MINIMUM_BALANCE\n ) {\n uint missingAmount = MINIMUM_BALANCE - balance;\n if (missingAmount < address(etherbase).balance) {\n etherbase.partiallyRetrieve(payable(msg.sender), missingAmount);\n } else {\n etherbase.retrieve(payable(msg.sender));\n }\n }\n }\n\n /**\n * @dev Calculate a message hash.\n */\n function _hashOfMessage(OutgoingMessageData memory message) private pure returns (bytes32) {\n bytes memory data = abi.encodePacked(\n message.dstChainHash,\n bytes32(message.msgCounter),\n bytes32(bytes20(message.srcContract)),\n bytes32(bytes20(message.dstContract)),\n message.data\n );\n return keccak256(data);\n } \n}\n" + }, + "contracts/schain/TokenManagerLinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMALinkerSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"../MessageProxy.sol\";\nimport \"./TokenManager.sol\";\n\n\n/**\n * @title TokenManagerLinker\n * @dev Links custom TokenManagers to MessageProxy.\n */\ncontract TokenManagerLinker is ITokenManagerLinker, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows to register new token manager.\n */\n bytes32 public constant REGISTRAR_ROLE = keccak256(\"REGISTRAR_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of {Linker} on mainnet.\n */\n address public linkerAddress;\n\n /**\n * @dev List of address of registered token managers.\n */\n ITokenManager[] public tokenManagers;\n\n // Deprecated variable\n bool private _interchainConnections;\n //\n\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {REGISTRAR_ROLE}.\n */\n modifier onlyRegistrar() {\n require(hasRole(REGISTRAR_ROLE, msg.sender), \"REGISTRAR_ROLE is required\");\n _;\n }\n\n /**\n * @dev Register new token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker)\n external\n override\n initializer\n {\n require(linker != address(0), \"Linker address has to be set\");\n\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(REGISTRAR_ROLE, msg.sender);\n messageProxy = newMessageProxyAddress; \n\t linkerAddress = linker;\n\n // fake usage of variable\n delete _interchainConnections;\n } \n\n /**\n * @dev Adds new TokenManager.\n */\n function registerTokenManager(ITokenManager newTokenManager) external override onlyRegistrar {\n tokenManagers.push(newTokenManager);\n }\n\n /**\n * @dev Cancel registration of token manager.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function removeTokenManager(ITokenManager tokenManagerAddress) external override onlyRegistrar {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManagerAddress) {\n break;\n }\n }\n if (index < length) {\n if (index < length - 1) {\n tokenManagers[index] = tokenManagers[length - 1];\n }\n tokenManagers.pop();\n }\n }\n\n /**\n * @dev Register new SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n * - Direct messaging between SKALE chains must be allowed.\n * - Amount of token managers on target SKALE chain must be equal to the amount on current one.\n */\n function connectSchain(\n string calldata schainName\n )\n external\n override\n onlyRegistrar\n {\n for (uint i = 0; i < tokenManagers.length; i++) {\n tokenManagers[i].addTokenManager(schainName, address(tokenManagers[i]));\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Cancel registration of linked SKALE chain.\n * \n * Requirements:\n * \n * - Function caller has to be granted with {REGISTRAR_ROLE}.\n */\n function disconnectSchain(string calldata schainName) external override onlyRegistrar {\n uint length = tokenManagers.length;\n for (uint i = 0; i < length; i++) {\n tokenManagers[i].removeTokenManager(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Check if {tokenManager} is registered in IMA.\n */\n function hasTokenManager(ITokenManager tokenManager) external view override returns (bool) {\n uint index;\n uint length = tokenManagers.length;\n for (index = 0; index < length; index++) {\n if (tokenManagers[index] == tokenManager) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @dev Check if SKALE chain with name {schainName} is registered in IMA.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = tokenManagers.length;\n connected = true;\n for (uint i = 0; i < length; i++) {\n connected = connected && tokenManagers[i].hasTokenManager(schainName);\n }\n connected = connected && messageProxy.isConnectedChain(schainName);\n }\n}\n" + }, + "contracts/schain/CommunityLocker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityLocker.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol\";\n\nimport \"../Messages.sol\";\n\ninterface ICommunityLockerInitializer is ICommunityLocker {\n function initializeTimestamp() external;\n}\n\n\n/**\n * @title CommunityLocker\n * @dev Contract contains logic to perform automatic reimbursement\n * of gas fees for sent messages\n */\ncontract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {\n\n /**\n * @dev Mainnet identifier.\n */\n string constant public MAINNET_NAME = \"Mainnet\";\n\n /**\n * @dev Keccak256 hash of mainnet name.\n */\n bytes32 constant public MAINNET_HASH = keccak256(abi.encodePacked(MAINNET_NAME));\n\n /**\n * @dev id of a role that allows changing of the contract parameters.\n */\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n /**\n * @dev Address of MessageProxyForSchain.\n */\n IMessageProxyForSchain public messageProxy;\n\n /**\n * @dev Address of TokenManagerLinker.\n */\n ITokenManagerLinker public tokenManagerLinker;\n\n /**\n * @dev Address of CommunityPool on mainnet.\n */\n address public communityPool;\n\n /**\n * @dev Keccak256 hash of schain name.\n */\n bytes32 public schainHash;\n\n // Disable slither check due to variable depreciation\n // and unavailability of making it constant because\n // it breaks upgradeability pattern.\n // slither-disable-next-line constable-states\n uint private _deprecatedTimeLimitPerMessage;\n\n /**\n * @dev Mapping of users who are allowed to send a message.\n */\n // user address => allowed to send message\n mapping(address => bool) public activeUsers;\n\n /**\n * @dev Timestamp of previous sent message by user.\n */\n // user address => timestamp of last message\n mapping(address => uint) public lastMessageTimeStamp;\n\n /**\n * @dev mainnet gas price(baseFee) value\n */\n uint256 public mainnetGasPrice;\n\n /**\n * @dev Timestamp of previous set of mainnet gas price\n */\n uint256 public gasPriceTimestamp;\n\n /**\n * @dev Amount of seconds after message sending\n * when next message cannot be sent.\n */\n // schainHash => time limit\n mapping(bytes32 => uint) public timeLimitPerMessage;\n\n /**\n * @dev Timestamp of previous sent message by user during\n * schain to schain transfers\n */\n // schainHash => user => timestamp\n mapping(bytes32 => mapping(address => uint)) public lastMessageTimeStampToSchain;\n\n /**\n * @dev Emitted when a user becomes active.\n */\n event ActivateUser(\n bytes32 schainHash,\n address user\n );\n\n /**\n * @dev Emitted when a user stops being active.\n */\n event LockUser(\n bytes32 schainHash,\n address user\n ); \n\n /**\n * @dev Emitted when constants updated.\n */\n event ConstantUpdated(\n bytes32 indexed constantHash,\n uint previousValue,\n uint newValue\n );\n\n modifier checkUserBeforeTransfer(bytes32 chainHash, address user) {\n uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];\n if (chainHash == MAINNET_HASH) {\n require(activeUsers[user], \"Recipient must be active\");\n lastTimestamp = lastMessageTimeStamp[user];\n }\n require(\n lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,\n \"Exceeded message rate limit\"\n );\n _;\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the caller of the function.\n * - CommunityPool must be an origin of the message on mainnet.\n * - The message must come from the mainnet.\n * - The message must contains status of a user.\n * - Status of a user in the message must be different from the current status.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n require(msg.sender == address(messageProxy), \"Sender is not a message proxy\");\n require(sender == communityPool, \"Sender must be CommunityPool\");\n require(fromChainHash == MAINNET_HASH, \"Source chain name must be Mainnet\");\n Messages.MessageType operation = Messages.getMessageType(data);\n require(operation == Messages.MessageType.USER_STATUS, \"The message should contain a status of user\");\n Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);\n require(activeUsers[message.receiver] != message.isActive, \"Active user statuses must be different\");\n activeUsers[message.receiver] = message.isActive;\n if (message.isActive) {\n emit ActivateUser(schainHash, message.receiver);\n } else {\n emit LockUser(schainHash, message.receiver);\n }\n }\n\n /**\n * @dev Reverts if {receiver} is not allowed to send a message.\n *\n * Requirements:\n * \n * - Function caller has to be registered in TokenManagerLinker as a TokenManager.\n * - {receiver} must be an active user.\n * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time\n * or there are no messages sent by {receiver}.\n */\n function checkAllowedToSendMessage(bytes32 chainHash, address receiver)\n external\n checkUserBeforeTransfer(chainHash, receiver)\n override\n {\n require(\n tokenManagerLinker.hasTokenManager(ITokenManager(msg.sender)),\n \"Sender is not registered token manager\"\n );\n if (chainHash == MAINNET_HASH) {\n lastMessageTimeStamp[receiver] = block.timestamp;\n } else {\n lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;\n }\n }\n\n /**\n * @dev Set value of {timeLimitPerMessage} of given chain.\n *\n * Requirements:\n * \n * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"Not enough permissions to set constant\");\n bytes32 chainHash = keccak256(abi.encodePacked(chainName));\n require(chainHash != schainHash, \"Incorrect chain\");\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"TimeLimitPerMessage\")),\n timeLimitPerMessage[chainHash],\n newTimeLimitPerMessage\n );\n timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;\n }\n\n /**\n * @dev Set value of {mainnetGasPrice}.\n *\n * Requirements:\n * \n * - Signature should be verified.\n * \n * Emits a {ConstantUpdated} event.\n */\n function setGasPrice(\n uint gasPrice,\n uint timestamp,\n IMessageProxyForSchain.Signature memory\n )\n external\n override\n {\n require(timestamp > gasPriceTimestamp, \"Gas price timestamp already updated\");\n require(timestamp <= block.timestamp, \"Timestamp should not be in the future\");\n // TODO: uncomment when oracle finished\n // require(\n // messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),\n // \"Signature is not verified\"\n // );\n emit ConstantUpdated(\n keccak256(abi.encodePacked(\"MainnetGasPrice\")),\n mainnetGasPrice,\n gasPrice\n );\n mainnetGasPrice = gasPrice;\n gasPriceTimestamp = timestamp;\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newSchainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newTokenManagerLinker,\n address newCommunityPool\n )\n external\n override\n initializer\n {\n require(newCommunityPool != address(0), \"Node address has to be set\");\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n messageProxy = newMessageProxy;\n tokenManagerLinker = newTokenManagerLinker;\n schainHash = keccak256(abi.encodePacked(newSchainName));\n timeLimitPerMessage[MAINNET_HASH] = 5 minutes;\n communityPool = newCommunityPool;\n }\n\n /**\n * @dev Initialize timestamp after upgrade and should be removed after upgrade\n *\n * Requirements:\n * Should be called only by address which hold DEFAULT_ADMIN_ROLE role\n */\n function initializeTimestamp() external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Incorrect sender\");\n // Disable slither check due to moving data to the new data structure\n // slither-disable-next-line uninitialized-state\n timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;\n delete _deprecatedTimeLimitPerMessage;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbaseUpgradeable.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\n\nimport \"./IEtherbase.sol\";\n\ninterface IEtherbaseUpgradeable is IAccessControlUpgradeable, IEtherbase {\n function initialize(address schainOwner) external;\n // slither-disable-next-line naming-convention\n function ETHER_MANAGER_ROLE() external pure returns (bytes32); // solhint-disable-line func-name-mixedcase\n}" + }, + "contracts/schain/bls/SkaleVerifier.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SkaleVerifier.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"./Precompiled.sol\";\nimport \"./FieldOperations.sol\";\n\n/**\n * @title SkaleVerifier\n * @dev Contains verify function to perform BLS signature verification.\n */\nlibrary SkaleVerifier {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point memory signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point memory publicKey\n )\n internal\n view\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB), \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB), \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return Precompiled.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return false;\n }\n\n return true;\n }\n}\n" + }, + "@skalenetwork/etherbase-interfaces/IEtherbase.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEtherbase.sol - Etherbase\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * Etherbase is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Etherbase is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with Etherbase. If not, see .\n */\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\ninterface IEtherbase {\n receive() external payable;\n function retrieve(address payable receiver) external;\n function partiallyRetrieve(address payable receiver, uint amount) external;\n}" + }, + "contracts/schain/bls/Precompiled.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n Precompiled.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\n/**\n * @title Precompiled\n * @dev This library is a wrapper to call precompiled contracts\n * \n * Defined calls:\n * \n * - bn256Pairing\n */\nlibrary Precompiled {\n\n /**\n * @dev Calls precompiled contract with address 0x8\n * for elliptic curve pairing operations are required in order to perform zkSNARK verification\n * within the block gas limit.\n * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details\n */\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n require(success, \"Pairing check failed\");\n return out[0] != 0;\n }\n}" + }, + "contracts/schain/bls/FieldOperations.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n FieldOperations.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n\n @author Dmytro Stebaiev\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol\";\n\nimport \"./Precompiled.sol\";\n\n\n/**\n * @title Fp2Operations\n * @dev This library contains operations of field that is an extension by imaginary unit of \n * a field of division remainders of a prime number\n * \n * Element of field is Fp2Point\n * \n * Prime divisor is P\n * \n * Defined operations:\n * \n * - addition\n * - subtraction\n * - scalar multiplication\n * - multiplication\n * - squaring\n * - comparison for equality\n */\nlibrary Fp2Operations {\n\n /**\n * @dev Prime devisor\n */\n uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @dev Add {value1} to {value2}\n */\n function addFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });\n }\n\n /**\n * @dev Perform scalar multiplication of {value} by {scalar}\n */\n function scalarMulFp2(\n IFieldOperations.Fp2Point memory value,\n uint scalar\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });\n }\n\n /**\n * @dev Subtract {subtracted} from {diminished}\n */\n function minusFp2(\n IFieldOperations.Fp2Point memory diminished,\n IFieldOperations.Fp2Point memory subtracted\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory difference)\n {\n uint p = P;\n if (diminished.a >= subtracted.a) {\n difference.a = addmod(diminished.a, p - subtracted.a, p);\n } else {\n difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;\n }\n if (diminished.b >= subtracted.b) {\n difference.b = addmod(diminished.b, p - subtracted.b, p);\n } else {\n difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;\n }\n }\n\n /**\n * @dev Multiply {value1} by {value2}\n */\n function mulFp2(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory result)\n {\n uint p = P;\n IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({\n a: mulmod(value1.a, value2.a, p),\n b: mulmod(value1.b, value2.b, p)});\n result.a = addmod(\n point.a,\n mulmod(p - 1, point.b, p),\n p);\n result.b = addmod(\n mulmod(\n addmod(value1.a, value1.b, p),\n addmod(value2.a, value2.b, p),\n p),\n p - addmod(point.a, point.b, p),\n p);\n }\n\n /**\n * @dev Square {value}\n */\n function squaredFp2(\n IFieldOperations.Fp2Point memory value\n )\n internal\n pure\n returns (IFieldOperations.Fp2Point memory)\n {\n uint p = P;\n uint ab = mulmod(value.a, value.b, p);\n uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);\n return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.Fp2Point memory value1,\n IFieldOperations.Fp2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.a == value2.a && value1.b == value2.b;\n }\n}\n\n/**\n * @title G1Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2\n * \n * Element of the group is Fp2Point\n * \n * Prime divisor is Fp2Operations.P\n * \n * A group generator is {1, 2}\n * \n * Defined operations:\n * \n * - check if a point is in the group G1\n * - check if a point is in the field Fp2\n * - for x of Fp calculate -x\n */\nlibrary G1Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n /**\n * @dev Get G1 group generator\n */\n function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 1,\n b: 2\n });\n }\n\n /**\n * @dev Check if ({x], {y}) is a G1 element\n */\n function isG1Point(uint x, uint y) internal pure returns (bool) {\n uint p = Fp2Operations.P;\n return mulmod(y, y, p) == \n addmod(mulmod(mulmod(x, x, p), x, p), 3, p);\n }\n\n /**\n * @dev Check if {point} is a G1 element\n */\n function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return isG1Point(point.a, point.b);\n }\n\n /**\n * @dev Check if {point} is a Fp2 element\n */\n function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {\n return point.a < Fp2Operations.P && point.b < Fp2Operations.P;\n }\n\n /**\n * @dev For {y} of Fp calculate -y\n */\n function negate(uint y) internal pure returns (uint) {\n return (Fp2Operations.P - y) % Fp2Operations.P;\n }\n\n}\n\n/**\n * @title G2Operations\n * @dev This library contains operations of a group of elements {x, y}\n * where y^2 = x^3 + TWISTB and x and y are elements of Fp2\n * \n * Element of the group is G2Point\n * \n * Prime divisor is Fp2Operations.P\n * TWISTB is\n * {\n * 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n * 266929791119991161246907387137283842545076965332900288569378510910307636690\n * }\n * A group generator is\n * {\n * {\n * 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n * 11559732032986387107991004021392285783925812861821192530917403151452391805634\n * },\n * {\n * 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n * 4082367875863433681332203403145435568316851327593401208105741076214120093531\n * }\n * }\n * \n * Defined operations:\n * \n * - check if a point is in the group G2\n * - check if a point is zero element of group G2\n * - comparison for equality\n */\nlibrary G2Operations {\n using Fp2Operations for IFieldOperations.Fp2Point;\n\n\n /**\n * @dev Get value of TWISTB\n */\n function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.Fp2Point({\n a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,\n b: 266929791119991161246907387137283842545076965332900288569378510910307636690\n });\n }\n\n /**\n * @dev Get G2 group generator\n */\n function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,\n b: 11559732032986387107991004021392285783925812861821192530917403151452391805634\n }),\n y: IFieldOperations.Fp2Point({\n a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,\n b: 4082367875863433681332203403145435568316851327593401208105741076214120093531\n })\n });\n }\n\n /**\n * @dev Get G2 zero element\n */\n function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {\n // Current solidity version does not support Constants of non-value type\n // so we implemented this function\n return IFieldOperations.G2Point({\n x: IFieldOperations.Fp2Point({\n a: 0,\n b: 0\n }),\n y: IFieldOperations.Fp2Point({\n a: 1,\n b: 0\n })\n });\n }\n\n /**\n * @dev Check if ({x}, {y}) is an element of G2\n */\n function isG2Point(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n if (isG2ZeroPoint(x, y)) {\n return true;\n }\n IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();\n IFieldOperations.Fp2Point memory res = squaredY.minusFp2(\n x.squaredFp2().mulFp2(x)\n ).minusFp2(getTWISTB());\n return res.a == 0 && res.b == 0;\n }\n\n /**\n * @dev Check if {value} is an element of G2\n */\n function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return isG2Point(value.x, value.y);\n }\n\n /**\n * @dev Check if ({x}, {y}) is a zero element of G2\n */\n function isG2ZeroPoint(\n IFieldOperations.Fp2Point memory x,\n IFieldOperations.Fp2Point memory y\n )\n internal\n pure\n returns (bool)\n {\n return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;\n }\n\n /**\n * @dev Check if {value} is a zero element of G2\n */\n function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {\n return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;\n }\n\n /**\n * @dev Check if {value1} is equal to {value2}\n */\n function isEqual(\n IFieldOperations.G2Point memory value1,\n IFieldOperations.G2Point memory value2\n )\n internal\n pure\n returns (bool)\n {\n return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);\n }\n}\n" + }, + "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./TokenManagerERC721.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title TokenManagerERC721WithMetadata\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC721 clones.\n * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC721WithMetadata is TokenManagerERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA\n ) {\n receiver = _sendERC721(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows TokenManager to send ERC721 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC721(bytes32 fromChainHash, bytes calldata data) internal override returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 tokenId;\n string memory tokenURI;\n ERC721OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n receiver = message.erc721message.receiver;\n token = message.erc721message.token;\n tokenId = message.erc721message.tokenId;\n tokenURI = message.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n } else {\n Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =\n Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);\n receiver = message.baseErc721transferWithMetadata.erc721message.receiver;\n token = message.baseErc721transferWithMetadata.erc721message.token;\n tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;\n tokenURI = message.baseErc721transferWithMetadata.tokenURI;\n contractOnSchain = clonesErc721[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol); \n clonesErc721[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&\n fromChainHash != MAINNET_HASH &&\n _isERC721AddedToSchain(fromChainHash, token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(fromChainHash, token, tokenId);\n IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);\n } else {\n contractOnSchain.mint(receiver, tokenId);\n contractOnSchain.setTokenURI(tokenId, tokenURI);\n }\n emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n {\n bool isMainChainToken;\n ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC721OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.getApproved(tokenId) == address(this), \"Not allowed ERC721 Token\");\n bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(\n contractOnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)\n );\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC721(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n } else {\n contractOnSchain.transferFrom(msg.sender, address(this), tokenId);\n contractOnSchain.burn(tokenId);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n bytes32 chainHash,\n address erc721OnMainChain,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);\n if (!isERC721AddedToSchain) {\n _addERC721ForSchain(chainHash, erc721OnMainChain);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainChain,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)\n );\n }\n emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "contracts/test/MessagesTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessagesTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../Messages.sol\";\n\n\ninterface IMessagesTester {\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure returns (bytes memory);\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure returns (bytes memory);\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure returns (bytes memory);\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure returns (bytes memory);\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeActivateUserMessage(address receiver) external pure returns (bytes memory);\n function encodeLockUserMessage(address receiver) external pure returns (bytes memory);\n function encodeInterchainConnectionMessage(bool isAllowed) external pure returns (bytes memory);\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure returns (bytes memory);\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure returns (bytes memory);\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure returns (bytes memory);\n}\n\n\ncontract MessagesTester is IMessagesTester {\n\n function encodeTransferEthMessage(address receiver, uint256 amount) external pure override returns (bytes memory) {\n return Messages.encodeTransferEthMessage(receiver, amount);\n }\n\n function encodeTransferErc20Message(\n address token,\n address receiver,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20Message(token, receiver, amount);\n }\n\n function encodeTransferErc20AndTotalSupplyMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTotalSupplyMessage(token, receiver, amount, totalSupply);\n }\n\n function encodeTransferErc20AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 amount,\n uint256 totalSupply,\n Messages.Erc20TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc20AndTokenInfoMessage(token, receiver, amount, totalSupply, tokenInfo);\n }\n\n function encodeTransferErc721Message(\n address token,\n address receiver,\n uint256 tokenId\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721Message(token, receiver, tokenId);\n }\n\n function encodeTransferErc721AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721AndTokenInfoMessage(token, receiver, tokenId, tokenInfo);\n }\n\n function encodeTransferErc721MessageWithMetadata(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721MessageWithMetadata(token, receiver, tokenId, tokenURI);\n }\n\n function encodeTransferErc721WithMetadataAndTokenInfoMessage(\n address token,\n address receiver,\n uint256 tokenId,\n string memory tokenURI,\n Messages.Erc721TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n token,\n receiver,\n tokenId,\n tokenURI,\n tokenInfo\n );\n }\n\n function encodeActivateUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeActivateUserMessage(receiver);\n }\n\n function encodeLockUserMessage(address receiver) external pure override returns (bytes memory) {\n return Messages.encodeLockUserMessage(receiver);\n }\n\n function encodeInterchainConnectionMessage(bool isAllowed) external pure override returns (bytes memory) {\n return Messages.encodeInterchainConnectionMessage(isAllowed);\n }\n\n function encodeTransferErc1155Message(\n address token,\n address receiver,\n uint256 id,\n uint256 amount\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155Message(token, receiver, id, amount);\n }\n\n function encodeTransferErc1155AndTokenInfoMessage(\n address token,\n address receiver,\n uint256 id,\n uint256 amount,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155AndTokenInfoMessage(token, receiver, id, amount, tokenInfo);\n }\n\n function encodeTransferErc1155BatchMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchMessage(token, receiver, ids, amounts);\n }\n\n function encodeTransferErc1155BatchAndTokenInfoMessage(\n address token,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts,\n Messages.Erc1155TokenInfo memory tokenInfo\n ) external pure override returns (bytes memory) {\n return Messages.encodeTransferErc1155BatchAndTokenInfoMessage(token, receiver, ids, amounts, tokenInfo);\n }\n}" + }, + "contracts/schain/TokenManagers/TokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerEth\n * @dev Runs on SKALE Chains and\n * accepts messages from mainnet.\n * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerEth is TokenManager, ITokenManagerEth {\n\n IEthErc20 public ethErc20;\n\n /// Create a new token manager \n\n /**\n * @dev Register EthErc20 token.\n */\n function setEthErc20Address(IEthErc20 newEthErc20Address) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(ethErc20 != newEthErc20Address, \"Must be new address\");\n ethErc20 = newEthErc20Address;\n }\n\n /**\n * @dev Move ETH from schain to mainnet.\n * \n * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.\n */\n function exitToMain(uint256 amount) external override {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);\n address receiver = decodedMessage.receiver;\n require(receiver != address(0), \"Incorrect receiver\");\n ethErc20.mint(receiver, decodedMessage.amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n ethErc20 = ethErc20Address;\n }\n\n // private\n\n /**\n * @dev Checks whether sender contract is DepositBox.\n */\n function _checkSender(bytes32 fromChainHash, address sender) internal view override returns (bool) {\n return fromChainHash == MAINNET_HASH && sender == depositBox;\n }\n\n /**\n * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address to,\n uint256 amount\n )\n private\n {\n if (amount > 0) {\n ethErc20.forceBurn(msg.sender, amount);\n }\n bytes memory data = Messages.encodeTransferEthMessage(to, amount);\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerEth - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../tokens/IEthErc20.sol\";\nimport \"../ICommunityLocker.sol\";\nimport \"../IMessageProxyForSchain.sol\";\nimport \"../ITokenManager.sol\";\nimport \"../ITokenManagerLinker.sol\";\n\n\ninterface ITokenManagerEth is ITokenManager {\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox,\n IEthErc20 ethErc20Address\n ) external;\n function setEthErc20Address(IEthErc20 newEthErc20Address) external;\n function exitToMain(uint256 amount) external;\n}" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IEthErc20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IEthErc20 {\n function mint(address account, uint256 amount) external;\n function forceBurn(address account, uint256 amount) external;\n function initialize(address tokenManagerEthAddress) external;\n}" + }, + "contracts/schain/TokenManagers/TokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC20OnChain.sol\";\nimport \"../TokenManager.sol\";\n\n\n/**\n * @title TokenManagerERC20\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC20 clones.\n * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC20 on Mainnet => ERC20 on Schain\n mapping(address => ERC20OnChain) public deprecatedClonesErc20;\n \n // address of clone on schain => totalSupplyOnMainnet\n mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;\n\n // address clone on schain => added or not\n mapping(ERC20OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC20OnChain)) public clonesErc20;\n\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n /**\n * @dev Emitted when schain owner register new ERC20 clone.\n */\n event ERC20TokenAdded(bytes32 indexed chainHash, address indexed erc20OnMainChain, address indexed erc20OnSchain);\n\n /**\n * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.\n */\n event ERC20TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC20TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc20OnMainChain,\n address indexed erc20OnSchain,\n uint256 amount\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(bytes32 indexed chainHash, address indexed contractOnMainnet, uint256 amount);\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.\n */\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {msg.sender} address.\n */\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, amount);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManager addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC20 ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||\n operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY\n ) {\n receiver = _sendERC20(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.\n */\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainChain,\n address erc20OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc20OnSchain.isContract(), \"Given address is not a contract\");\n require(ERC20OnChain(erc20OnSchain).totalSupply() == 0, \"TotalSupply is not zero\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc20[targetChainHash][erc20OnMainChain]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC20OnChain(erc20OnSchain)], \"Clone was already added\");\n clonesErc20[targetChainHash][erc20OnMainChain] = ERC20OnChain(erc20OnSchain);\n addedClones[ERC20OnChain(erc20OnSchain)] = true;\n emit ERC20TokenAdded(targetChainHash, erc20OnMainChain, erc20OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override \n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n // private\n\n /**\n * @dev Allows TokenManager to send ERC20 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC20(bytes32 fromChainHash, bytes calldata data) private returns (address) { \n Messages.MessageType messageType = Messages.getMessageType(data);\n (address receiver, address token, uint256 amount) = _decodeErc20Message(data);\n ERC20OnChain contractOnSchain;\n if (messageType != Messages.MessageType.TRANSFER_ERC20) {\n uint256 totalSupply;\n if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory message =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory message =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n totalSupply = message.totalSupply;\n contractOnSchain = clonesErc20[fromChainHash][token];\n\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);\n clonesErc20[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {\n totalSupplyOnMainnet[contractOnSchain] = totalSupply;\n }\n bool noOverflow;\n uint updatedTotalSupply;\n (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);\n require(\n noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],\n \"Total supply exceeded\"\n );\n contractOnSchain.mint(receiver, amount);\n } else {\n require(token.isContract() && _schainToERC20[fromChainHash].contains(token), \"Incorrect main chain token\");\n require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, \"Not enough money\");\n _removeTransferredAmount(fromChainHash, token, amount);\n require(\n ERC20Upgradeable(token).transfer(receiver, amount),\n \"Transfer was failed\"\n );\n }\n emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC20OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.balanceOf(msg.sender) >= amount, \"Insufficient funds\");\n require(\n contractOnSchain.allowance(\n msg.sender,\n address(this)\n ) >= amount,\n \"Transfer is not approved by token holder\"\n );\n bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC20(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n amount\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), amount);\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n } else {\n require(\n contractOnSchain.transferFrom(msg.sender, address(this), amount),\n \"Transfer was failed\"\n );\n contractOnSchain.burn(amount);\n }\n messageProxy.postOutgoingMessage(\n chainHash,\n messageReceiver,\n data\n );\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 chainHash, address erc20Token, uint256 amount) private {\n transferredAmount[chainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n * \n * Emits an {ERC20TokenReady} event.\n * \n * Requirements:\n * \n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n bytes32 chainHash,\n address erc20OnMainChain,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);\n if (!isERC20AddedToSchain) {\n _addERC20ForSchain(chainHash, erc20OnMainChain);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainChain,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n * \n * Emits an {ERC20TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC20ForSchain(bytes32 chainHash, address erc20OnMainChain) private {\n require(erc20OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[chainHash].contains(erc20OnMainChain), \"ERC20 Token was already added\");\n _schainToERC20[chainHash].add(erc20OnMainChain);\n emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n\n\n /**\n * @dev Decodes ERC20 transfer message depending on type of message.\n */\n function _decodeErc20Message(bytes calldata data)\n private\n pure\n returns (address, address, uint256)\n {\n Messages.MessageType messageType = Messages.getMessageType(data);\n if (messageType == Messages.MessageType.TRANSFER_ERC20) {\n Messages.TransferErc20Message memory message =\n Messages.decodeTransferErc20Message(data);\n return (\n message.receiver,\n message.token,\n message.amount\n );\n } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {\n Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =\n Messages.decodeTransferErc20AndTotalSupplyMessage(data);\n return (\n messageTotalSupply.baseErc20transfer.receiver,\n messageTotalSupply.baseErc20transfer.token,\n messageTotalSupply.baseErc20transfer.amount\n );\n } else {\n Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =\n Messages.decodeTransferErc20AndTokenInfoMessage(data);\n return (\n messageTokenInfo.baseErc20transfer.receiver,\n messageTokenInfo.baseErc20transfer.token,\n messageTokenInfo.baseErc20transfer.amount\n );\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\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 /**\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 `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, 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 `from` to `to` 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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMathUpgradeable {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\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) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\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 *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\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 *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\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 *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting 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 *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting 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 *\n * - The divisor cannot be zero.\n */\n function div(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\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 *\n * - The divisor cannot be zero.\n */\n function mod(\n uint256 a,\n uint256 b,\n string memory errorMessage\n ) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC20 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\ninterface ITokenManagerERC20 is ITokenContractManager {\n function exitToMainERC20(\n address contractOnMainnet,\n uint256 amount\n ) external;\n function transferToSchainERC20(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 amount\n ) external;\n function addERC20TokenByOwner(\n string calldata targetChainName,\n address erc20OnMainnet,\n address erc20OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC20OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol\";\n\n\n/**\n * @title ERC20OnChain\n * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.\n */\ncontract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory contractName,\n string memory contractSymbol\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);\n ERC20BurnableUpgradeable.__ERC20Burnable_init();\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 value) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC20OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC20OnChain {\n function mint(address account, uint256 value) external;\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 {ERC20PresetMinterPauser}.\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 Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override 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 virtual override 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. This is the value {ERC20} uses, unless this function is\n * overridden;\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 virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, 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 * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\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 virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + 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 virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This 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 * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, 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 * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(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 virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This 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(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\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.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/test/EtherbaseMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EtherbaseMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol\";\n\n\ncontract EtherbaseMock is IEtherbaseUpgradeable, AccessControlEnumerableUpgradeable {\n bytes32 public constant override ETHER_MANAGER_ROLE = keccak256(\"ETHER_MANAGER_ROLE\");\n\n event EtherReceived(\n address sender,\n uint amount\n );\n\n event EtherSent(\n address receiver,\n uint amount\n );\n\n modifier onlyEtherManager() {\n require(hasRole(ETHER_MANAGER_ROLE, msg.sender), \"ETHER_MANAGER_ROLE is required\");\n _;\n }\n\n receive() external payable override {\n emit EtherReceived(msg.sender, msg.value);\n }\n\n function retrieve(address payable receiver) external override onlyEtherManager {\n partiallyRetrieve(receiver, address(this).balance);\n }\n\n function initialize(address schainOwner) external initializer override\n {\n AccessControlUpgradeable.__AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, schainOwner);\n _setupRole(ETHER_MANAGER_ROLE, schainOwner);\n }\n\n function partiallyRetrieve(address payable receiver, uint amount) public override onlyEtherManager {\n require(receiver != address(0), \"Receiver address is not set\");\n require(amount <= address(this).balance, \"Insufficient funds\");\n\n emit EtherSent(receiver, amount);\n\n receiver.transfer(amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the 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 virtual onlyOwner {\n _transferOwnership(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 virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/test/erc20/RevertableERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * RevertableERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ninterface IRevertableERC20 {\n function enable() external;\n function disable() external;\n function mint(address account, uint amount) external;\n}\n\ncontract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {\n bool public enabled = true;\n\n constructor(string memory name, string memory symbol) initializer {\n super.__ERC20_init(name, symbol);\n }\n\n function enable() external override {\n enabled = true;\n }\n\n function disable() external override {\n enabled = false;\n }\n\n function mint(address account, uint amount) external override {\n _mint(account, amount);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n override\n {\n require(enabled, \"Transfers are disabled\");\n super._transfer(from, to, amount);\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.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 IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\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(IERC20Upgradeable 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. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "contracts/test/TestContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestContractManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\ninterface IContractManagerTester {\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function getContract(string memory contractName) external view returns (address);\n}\n\ncontract ContractManager is IContractManagerTester {\n using AddressUpgradeable for address;\n\n // mapping of actual smart contracts addresses\n mapping (bytes32 => address) public contracts;\n\n address public owner;\n\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * Adds actual contract to mapping of actual contract addresses\n * @param contractsName - contracts name in skale manager system\n * @param newContractsAddress - contracts address in skale manager system\n */\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external override {\n // check newContractsAddress is not equal zero\n require(newContractsAddress != address(0), \"New address is equal zero\");\n // create hash of contractsName\n bytes32 contractId = keccak256(abi.encodePacked(contractsName));\n // check newContractsAddress is not equal the previous contract's address\n require(contracts[contractId] != newContractsAddress, \"Contract is already added\");\n // check newContractsAddress contains code\n require(newContractsAddress.isContract(), \"Given contracts address is not contain code\");\n // add newContractsAddress to mapping of actual contract addresses\n contracts[contractId] = newContractsAddress;\n emit ContractUpgraded(contractsName, newContractsAddress);\n }\n\n /**\n * @dev Returns the contract address for a given contractName.\n */\n function getContract(string memory contractName) external view override returns (address) {\n return contracts[keccak256(abi.encodePacked(contractName))];\n }\n}\n" + }, + "contracts/test/TestSchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchainsInternal.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./TestNodes.sol\";\n\n\ninterface ISchainsInternalTester {\n function addContractManager(address newContractManager) external;\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external;\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external;\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n}\n\n\ncontract SchainsInternal is ISchainsInternalTester {\n\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n }\n\n ContractManager public contractManager;\n\n mapping (bytes32 => Schain) public schains;\n\n mapping (bytes32 => bool) public isSchainActive;\n\n mapping (bytes32 => uint[]) public schainsGroups;\n\n bytes32[] public schainsAtSystem;\n\n mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function initializeSchain(\n string calldata name,\n address from,\n uint lifetime,\n uint deposit) external override\n {\n bytes32 schainHash = keccak256(abi.encodePacked(name));\n schains[schainHash].name = name;\n schains[schainHash].owner = from;\n schains[schainHash].startDate = block.timestamp;\n schains[schainHash].startBlock = block.number;\n schains[schainHash].lifetime = lifetime;\n schains[schainHash].deposit = deposit;\n schains[schainHash].index = 1337;\n isSchainActive[schainHash] = true;\n schainsAtSystem.push(schainHash);\n }\n\n function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {\n Nodes nodesContract = Nodes(contractManager.getContract(\"Nodes\"));\n schainsGroups[schainHash] = nodes;\n for (uint i = 0; i < nodes.length; i++) {\n address nodeAddress = nodesContract.getNodeAddress(nodes[i]);\n _nodeAddressInSchain[schainHash][nodeAddress] = true;\n }\n }\n\n function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {\n return _nodeAddressInSchain[schainHash][sender];\n }\n\n function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {\n return schains[schainHash].owner == from;\n }\n\n function getSchains() external view override returns (bytes32[] memory) {\n return schainsAtSystem;\n }\n\n function getSchainName(bytes32 schainHash)\n external\n view\n override\n returns (string memory)\n {\n return schains[schainHash].name;\n }\n\n function getNodesInGroup(bytes32 schainHash)\n external\n view\n override\n returns (uint[] memory)\n {\n return schainsGroups[schainHash];\n }\n\n function isSchainExist(bytes32) external pure override returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/test/TestNodes.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestNodes.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\n\ninterface INodesTester {\n function createNode(address, Nodes.NodeCreationParams calldata params) external;\n function getNodeAddress(uint nodeIndex) external view returns (address);\n function isNodeExist(address from, uint nodeIndex) external view returns (bool);\n}\n\n\ncontract Nodes is INodesTester {\n\n enum NodeStatus {Active, Leaving, Left, In_Maintenance}\n\n struct Node {\n string name;\n bytes4 ip;\n bytes4 publicIP;\n uint16 port;\n bytes32[2] publicKey;\n uint startBlock;\n uint lastRewardDate;\n uint finishTime;\n NodeStatus status;\n uint validatorId;\n }\n\n struct NodeCreationParams {\n string name;\n bytes4 ip;\n bytes4 publicIp;\n uint16 port;\n bytes32[2] publicKey;\n uint16 nonce;\n string domainName;\n }\n\n struct CreatedNodes {\n mapping (uint => bool) isNodeExist;\n uint numberOfNodes;\n }\n\n Node[] public nodes;\n\n mapping (address => CreatedNodes) public nodeIndexes;\n\n modifier checkNodeExists(uint nodeIndex) {\n _checkNodeIndex(nodeIndex);\n _;\n }\n\n function createNode(address from, NodeCreationParams calldata params)\n external override\n {\n nodes.push(Node({\n name: params.name,\n ip: params.ip,\n publicIP: params.publicIp,\n port: params.port,\n publicKey: params.publicKey,\n startBlock: block.number,\n lastRewardDate: block.timestamp,\n finishTime: 0,\n status: NodeStatus.Active,\n validatorId: 1337\n }));\n nodeIndexes[from].isNodeExist[nodes.length - 1] = true;\n nodeIndexes[from].numberOfNodes++;\n }\n\n function getNodeAddress(uint nodeIndex)\n external\n view\n override\n checkNodeExists(nodeIndex)\n returns (address)\n {\n return _publicKeyToAddress(nodes[nodeIndex].publicKey);\n }\n\n function isNodeExist(address from, uint nodeIndex)\n public\n view\n override\n checkNodeExists(nodeIndex)\n returns (bool)\n {\n return nodeIndexes[from].isNodeExist[nodeIndex];\n }\n\n function _checkNodeIndex(uint nodeIndex) private view {\n require(nodeIndex < nodes.length, \"Node with such index does not exist\");\n }\n\n function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address) {\n bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));\n bytes20 addr;\n for (uint8 i = 12; i < 32; i++) {\n addr |= bytes20(hash[i] & 0xFF) >> ((i - 12) * 8);\n }\n return address(addr);\n }\n}\n" + }, + "contracts/test/TestWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestWallets.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./TestSchainsInternal.sol\";\n\ninterface IWalletsTester {\n function addContractManager(address newContractManager) external;\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n ) external;\n function rechargeSchainWallet(bytes32 schainHash) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n}\n\n\ncontract Wallets is IWalletsTester {\n\n ContractManager public contractManager;\n\n mapping (bytes32 => uint) private _schainWallets;\n\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function refundGasBySchain(\n bytes32 schainHash,\n address payable spender,\n uint spentGas,\n bool\n )\n external\n override\n {\n uint amount = tx.gasprice * spentGas;\n require(schainHash != bytes32(0), \"SchainHash cannot be null\");\n require(amount <= _schainWallets[schainHash], \"Schain wallet has not enough funds\");\n _schainWallets[schainHash] -= amount;\n emit NodeRefundedBySchain(spender, schainHash, amount);\n spender.transfer(amount);\n }\n\n function rechargeSchainWallet(bytes32 schainHash) external payable override {\n SchainsInternal schainsInternal = SchainsInternal(contractManager.getContract(\"SchainsInternal\"));\n require(schainsInternal.isSchainActive(schainHash), \"Schain should be active for recharging\");\n _schainWallets[schainHash] += msg.value;\n emit SchainWalletRecharged(msg.sender, msg.value, schainHash);\n }\n\n function getSchainBalance(bytes32 schainHash) external view override returns (uint) {\n return _schainWallets[schainHash];\n }\n}\n" + }, + "contracts/test/TestSchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSchains.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"./TestContractManager.sol\";\nimport \"./KeyStorageMock.sol\";\nimport \"./SkaleVerifierMock.sol\";\n\n\ninterface ISchainsTester {\n function addContractManager(address newContractManager) external;\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n}\n\n\ncontract Schains is ISchainsTester {\n\n ContractManager public contractManager;\n\n function addContractManager(address newContractManager) external override {\n contractManager = ContractManager(newContractManager);\n }\n\n function verifySchainSignature(\n uint signatureA,\n uint signatureB,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n string calldata schainName\n )\n external\n view\n override\n returns (bool)\n {\n SkaleVerifierMock skaleVerifier = SkaleVerifierMock(contractManager.getContract(\"SkaleVerifier\"));\n IFieldOperations.G2Point memory publicKey = KeyStorageMock(\n contractManager.getContract(\"KeyStorage\")\n ).getBlsCommonPublicKeyForSchain(\n keccak256(abi.encodePacked(schainName))\n );\n return skaleVerifier.verify(\n IFieldOperations.Fp2Point({\n a: signatureA,\n b: signatureB\n }),\n hash, counter,\n hashA, hashB,\n publicKey\n );\n }\n}\n" + }, + "contracts/test/KeyStorageMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * KeyStorageMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/KeyStorage.sol\";\n\n\ninterface IKeyStorageMock is IKeyStorage {\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external;\n function setBlsCommonPublicKeyForSchain(bytes32 schainHash, IFieldOperations.G2Point calldata key) external;\n function getBlsCommonPublicKeyForSchain(bytes32 schainHash) external view returns (IFieldOperations.G2Point memory);\n}\n\n\ncontract KeyStorageMock is KeyStorage, IKeyStorageMock {\n \n IFieldOperations.G2Point public blsCommonPublicKey;\n mapping (bytes32 => IFieldOperations.G2Point) public blsCommonPublicKeys;\n string public hello = \"Hello\";\n\n function setBlsCommonPublicKey(IFieldOperations.G2Point calldata key) external override {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKey = _key; \n }\n\n function setBlsCommonPublicKeyForSchain(\n bytes32 schainHash,\n IFieldOperations.G2Point calldata key\n )\n external\n override\n {\n // TODO: remove when update compiler will be updated\n IFieldOperations.G2Point memory _key = key;\n blsCommonPublicKeys[schainHash] = _key;\n }\n\n function getBlsCommonPublicKey()\n external\n view\n override(IKeyStorage, KeyStorage)\n returns (IFieldOperations.G2Point memory)\n {\n require(\n !(blsCommonPublicKey.x.a == 0 &&\n blsCommonPublicKey.x.b == 0 &&\n blsCommonPublicKey.y.a == 0 &&\n blsCommonPublicKey.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return blsCommonPublicKey;\n }\n\n function getBlsCommonPublicKeyForSchain(\n bytes32 schainHash\n )\n external\n view\n override\n returns (IFieldOperations.G2Point memory)\n {\n IFieldOperations.G2Point memory key = blsCommonPublicKeys[schainHash];\n require(\n !(key.x.a == 0 &&\n key.x.b == 0 &&\n key.y.a == 0 &&\n key.y.b == 0),\n \"BLS common public key is not set in the mock\"\n );\n return key;\n }\n}\n\n" + }, + "contracts/test/SkaleVerifierMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestSkaleVerifier.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"../schain/bls/FieldOperations.sol\";\n\nimport \"./PrecompiledMock.sol\";\n\n\ninterface ISkaleVerifierMock {\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n returns (bool);\n}\n\n\ncontract SkaleVerifierMock is ISkaleVerifierMock {\n\n /**\n * @dev Verifies a BLS signature.\n * \n * Requirements:\n * \n * - Signature is in G1.\n * - Hash is in G1.\n * - G2.one in G2.\n * - Public Key in G2.\n */\n function verify(\n IFieldOperations.Fp2Point calldata signature,\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB,\n IFieldOperations.G2Point calldata publicKey\n )\n external\n view\n override\n returns (bool)\n {\n require(G1Operations.checkRange(signature), \"Signature is not valid\");\n if (!_checkHashToGroupWithHelper(\n hash,\n counter,\n hashA,\n hashB\n )\n )\n {\n return false;\n }\n\n uint newSignB = G1Operations.negate(signature.b);\n require(G1Operations.isG1Point(signature.a, newSignB) || true, \"Sign not in G1\");\n require(G1Operations.isG1Point(hashA, hashB) || true, \"Hash not in G1\");\n\n IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();\n require(\n G2Operations.isG2(publicKey),\n \"Public Key not in G2\"\n );\n\n return PrecompiledMock.bn256Pairing(\n signature.a, newSignB,\n g2.x.b, g2.x.a, g2.y.b, g2.y.a,\n hashA, hashB,\n publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a\n );\n // return true;\n }\n\n function _checkHashToGroupWithHelper(\n bytes32 hash,\n uint counter,\n uint hashA,\n uint hashB\n )\n private\n pure\n returns (bool)\n {\n if (counter > 100) {\n return false;\n }\n uint xCoordinate = uint(hash) % Fp2Operations.P;\n xCoordinate = (xCoordinate + counter) % Fp2Operations.P;\n\n uint ySquared = addmod(\n mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),\n 3,\n Fp2Operations.P\n );\n if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {\n return true;\n }\n\n return true;\n }\n}\n" + }, + "contracts/schain/KeyStorage.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/IKeyStorage.sol\";\n\nimport \"./bls/FieldOperations.sol\";\n\n\n/**\n * @title KeyStorage\n * @dev Holds common BLS public key.\n */\ncontract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {\n\n uint256 public constant FREE_MEM_PTR = 0x40;\n\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get uin256 value from the config.\n */\n uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;\n /**\n * @dev Address of custom precompiled contract on SKALE chain\n * to get current BLS public key.\n */\n uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize()\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @dev Get BLS common public key.\n */\n function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {\n return _getCurrentBLSPublicKey();\n }\n\n // private\n\n /**\n * @dev Get uint256 value from the skaled config.\n */\n function _getConfigVariableUint256(\n string memory strConfigVariableName\n )\n private\n view\n returns ( uint256 rv )\n {\n uint256 fmp = FREE_MEM_PTR;\n uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {\n let where := add(ptr, mul(32, i))\n let what := mload(add(strConfigVariableName, mul(32, i)))\n mstore(where, what)\n }\n success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)\n rv := mload(ptr)\n }\n require(success, \"Get config uint256 failed\");\n }\n\n /**\n * @dev Get current BLS public key the skaled.\n */\n function _getCurrentBLSPublicKey()\n private\n view\n returns ( IFieldOperations.G2Point memory pk )\n {\n uint256 fmp = FREE_MEM_PTR;\n bool success;\n uint xa;\n uint xb;\n uint ya;\n uint yb;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let ptr := mload(fmp)\n success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)\n xa := mload(ptr)\n xb := mload(add(ptr, 32))\n ya := mload(add(ptr, 64))\n yb := mload(add(ptr, 96))\n }\n pk.x.a = xa;\n pk.x.b = xb;\n pk.y.a = ya;\n pk.y.b = yb;\n require(success, \"Get current BLS public key failed\");\n }\n}\n" + }, + "contracts/test/PrecompiledMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TestPrecompiled.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\n\nlibrary PrecompiledMock {\n\n function bigModExp(uint base, uint power, uint modulus) internal view returns (uint) {\n uint[6] memory inputToBigModExp;\n inputToBigModExp[0] = 32;\n inputToBigModExp[1] = 32;\n inputToBigModExp[2] = 32;\n inputToBigModExp[3] = base;\n inputToBigModExp[4] = power;\n inputToBigModExp[5] = modulus;\n uint[1] memory out;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 5, inputToBigModExp, mul(6, 0x20), out, 0x20)\n }\n require(success, \"BigModExp failed\");\n return out[0];\n }\n\n function bn256ScalarMul(uint x, uint y, uint k) internal view returns (uint , uint ) {\n uint[3] memory inputToMul;\n uint[2] memory output;\n inputToMul[0] = x;\n inputToMul[1] = y;\n inputToMul[2] = k;\n bool success;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 7, inputToMul, 0x60, output, 0x40)\n }\n require(success, \"Multiplication failed\");\n return (output[0], output[1]);\n }\n\n function bn256Pairing(\n uint x1,\n uint y1,\n uint a1,\n uint b1,\n uint c1,\n uint d1,\n uint x2,\n uint y2,\n uint a2,\n uint b2,\n uint c2,\n uint d2)\n internal view returns (bool)\n {\n bool success;\n uint[12] memory inputToPairing;\n inputToPairing[0] = x1;\n inputToPairing[1] = y1;\n inputToPairing[2] = a1;\n inputToPairing[3] = b1;\n inputToPairing[4] = c1;\n inputToPairing[5] = d1;\n inputToPairing[6] = x2;\n inputToPairing[7] = y2;\n inputToPairing[8] = a2;\n inputToPairing[9] = b2;\n inputToPairing[10] = c2;\n inputToPairing[11] = d2;\n uint[1] memory out;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)\n }\n // require(success, \"Pairing check failed\");\n return true;\n }\n}" + }, + "contracts/test/TestCallReceiverContract.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract TestCallReceiverContract is IMessageReceiver {\n event Error(uint error);\n\n function postMessage(\n bytes32,\n address,\n bytes calldata data\n )\n external\n override\n {\n uint revertCode = abi.decode(data, (uint));\n uint one = 1;\n uint zero = 0;\n if (revertCode == 1) {\n revert(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\");\n } else if (revertCode == 2) {\n emit Error(one / zero);\n }\n }\n}" + }, + "contracts/test/ReceiverMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverMock is IMessageReceiver {\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n pure\n override\n {\n return;\n }\n}\n" + }, + "contracts/test/ReceiverGasLimitSchainMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitSchainMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "contracts/test/ReceiverGasLimitMainnetMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ReceiverMock.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/IMessageReceiver.sol\";\n\n\ncontract ReceiverGasLimitMainnetMock is IMessageReceiver {\n uint public a = 0;\n function postMessage(\n bytes32,\n address,\n bytes calldata\n )\n external\n override\n {\n while(true) {\n a++;\n }\n }\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\nimport \"../IGasReimbursable.sol\";\nimport \"../IMessageReceiver.sol\";\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface IDepositBox is ITwin, IMessageReceiver, IGasReimbursable {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function enableWhitelist(string memory schainName) external;\n function disableWhitelist(string memory schainName) external;\n function isWhitelisted(string memory schainName) external view returns (bool);\n}" + }, + "@skalenetwork/skale-manager-interfaces/IContractManager.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IContractManager.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IContractManager {\n /**\n * @dev Emitted when contract is upgraded.\n */\n event ContractUpgraded(string contractsName, address contractsAddress);\n\n function initialize() external;\n function setContractsAddress(string calldata contractsName, address newContractsAddress) external;\n function contracts(bytes32 nameHash) external view returns (address);\n function getDelegationPeriodManager() external view returns (address);\n function getBounty() external view returns (address);\n function getValidatorService() external view returns (address);\n function getTimeHelpers() external view returns (address);\n function getConstantsHolder() external view returns (address);\n function getSkaleToken() external view returns (address);\n function getTokenState() external view returns (address);\n function getPunisher() external view returns (address);\n function getContract(string calldata name) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ILinker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ILinker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITwin.sol\";\n\n\ninterface ILinker is ITwin {\n function registerMainnetContract(address newMainnetContract) external;\n function removeMainnetContract(address mainnetContract) external;\n function connectSchain(string calldata schainName, address[] calldata schainContracts) external;\n function kill(string calldata schainName) external;\n function disconnectSchain(string calldata schainName) external;\n function isNotKilled(bytes32 schainHash) external view returns (bool);\n function hasMainnetContract(address mainnetContract) external view returns (bool);\n function hasSchain(string calldata schainName) external view returns (bool connected);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IMessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IMessageProxy.sol\";\nimport \"./ICommunityPool.sol\";\n\ninterface IMessageProxyForMainnet is IMessageProxy {\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external;\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external;\n function setNewMessageGasCost(uint256 newMessageGasCost) external;\n function pause(string calldata schainName) external;\n function resume(string calldata schainName) external;\n function addReimbursedContract(string memory schainName, address reimbursedContract) external;\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external;\n function messageInProgress() external view returns (bool);\n function isPaused(bytes32 schainHash) external view returns (bool);\n function isReimbursedContract(bytes32 schainHash, address contractAddress) external view returns (bool);\n function getReimbursedContractsLength(bytes32 schainHash) external view returns (uint256);\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory contractsInRange);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ITwin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITwin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ISkaleManagerClient.sol\";\n\ninterface ITwin is ISkaleManagerClient {\n function addSchainContract(string calldata schainName, address contractReceiver) external;\n function removeSchainContract(string calldata schainName) external;\n function hasSchainContract(string calldata schainName) external view returns (bool);\n function getSchainContract(bytes32 schainHash) external view returns (address);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ISkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\ninterface ISkaleManagerClient {\n function initialize(IContractManager newContractManagerOfSkaleManager) external;\n function isSchainOwner(address sender, bytes32 schainHash) external view returns (bool);\n function isAgentAuthorized(bytes32 schainHash, address sender) external view returns (bool);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ICommunityPool.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\n\n\nimport \"./ILinker.sol\";\nimport \"./IMessageProxyForMainnet.sol\";\nimport \"./ITwin.sol\";\n\n\ninterface ICommunityPool is ITwin {\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n ) external;\n function refundGasByUser(bytes32 schainHash, address payable node, address user, uint gas) external returns (uint);\n function rechargeUserWallet(string calldata schainName, address user) external payable;\n function withdrawFunds(string calldata schainName, uint amount) external;\n function setMinTransactionGas(uint newMinTransactionGas) external;\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external;\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n ) external returns (bool);\n function getBalance(address user, string calldata schainName) external view returns (uint);\n function checkUserBalance(bytes32 schainHash, address receiver) external view returns (bool);\n function getRecommendedRechargeAmount(bytes32 schainHash, address receiver) external view returns (uint256);\n}" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxEth is IDepositBox {\n receive() external payable;\n function deposit(string memory schainName) external payable;\n function getMyEth() external;\n function getFunds(string calldata schainName, address payable receiver, uint amount) external;\n function enableActiveEthTransfers(string calldata schainName) external;\n function disableActiveEthTransfers(string calldata schainName) external;\n}" + }, + "contracts/test/FallbackEthTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * FallbackEthTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2022-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\n\ninterface IFallbackEthTester {\n receive() external payable;\n function deposit() external payable;\n function rechargeUserWallet() external payable;\n function getMyEth() external;\n}\n\n\ncontract FallbackEthTester is IFallbackEthTester {\n IDepositBoxEth public depositBoxEth;\n ICommunityPool public communityPool;\n\n string public schainName;\n\n bool private _receiveInProgress;\n bool private _getMyEthInProgress;\n\n constructor(\n IDepositBoxEth newDepositBoxEth,\n ICommunityPool newCommunityPool,\n string memory newSchainName\n ) {\n depositBoxEth = newDepositBoxEth;\n communityPool = newCommunityPool;\n schainName = newSchainName;\n }\n\n receive() external payable override {\n if (!_receiveInProgress && !_getMyEthInProgress) {\n _receiveInProgress = true;\n uint256 balance = communityPool.getBalance(address(this), schainName);\n communityPool.withdrawFunds(schainName, balance);\n _receiveInProgress = false;\n }\n }\n\n function deposit() external payable override {\n depositBoxEth.deposit{value: msg.value}(schainName);\n }\n\n function rechargeUserWallet() external payable override {\n communityPool.rechargeUserWallet{value: msg.value}(schainName, address(this));\n }\n\n function getMyEth() external override {\n _getMyEthInProgress = true;\n depositBoxEth.getMyEth();\n _getMyEthInProgress = false;\n }\n}" + }, + "contracts/mainnet/MessageProxyForMainnet.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForMainnet.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchains.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\n\n\nimport \"../MessageProxy.sol\";\nimport \"./SkaleManagerClient.sol\";\nimport \"./CommunityPool.sol\";\n\n\n/**\n * @title Message Proxy for Mainnet\n * @dev Runs on Mainnet, contains functions to manage the incoming messages from\n * `targetSchainName` and outgoing messages to `fromSchainName`. Every SKALE chain with\n * IMA is therefore connected to MessageProxyForMainnet.\n *\n * Messages from SKALE chains are signed using BLS threshold signatures from the\n * nodes in the chain. Since Ethereum Mainnet has no BLS public key, mainnet\n * messages do not need to be signed.\n */\ncontract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessageProxyForMainnet {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n struct Pause {\n bool paused;\n }\n\n bytes32 public constant PAUSABLE_ROLE = keccak256(abi.encodePacked(\"PAUSABLE_ROLE\"));\n\n /**\n * 16 Agents\n * Synchronize time with time.nist.gov\n * Every agent checks if it is their time slot\n * Time slots are in increments of 10 seconds\n * At the start of their slot each agent:\n * For each connected schain:\n * Read incoming counter on the dst chain\n * Read outgoing counter on the src chain\n * Calculate the difference outgoing - incoming\n * Call postIncomingMessages function passing (un)signed message array\n * ID of this schain, Chain 0 represents ETH mainnet,\n */\n\n ICommunityPool public communityPool;\n\n uint256 public headerMessageGasCost;\n uint256 public messageGasCost;\n\n // disable detector until slither will fix this issue\n // https://github.com/crytic/slither/issues/456\n // slither-disable-next-line uninitialized-state\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _registryContracts;\n string public version;\n bool public override messageInProgress;\n\n // schainHash => Pause structure\n mapping(bytes32 => Pause) public pauseInfo;\n\n // schainHash => Set of addresses of reimbursed contracts\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _reimbursedContracts;\n\n /**\n * @dev Emitted when gas cost for message header was changed.\n */\n event GasCostMessageHeaderWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when gas cost for message was changed.\n */\n event GasCostMessageWasChanged(\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when the schain is paused\n */\n event SchainPaused(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when the schain is resumed\n */\n event SchainResumed(\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when reimbursed contract was added\n */\n event ReimbursedContractAdded(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Emitted when reimbursed contract was removed\n */\n event ReimbursedContractRemoved(\n bytes32 indexed schainHash,\n address contractAddress\n );\n\n /**\n * @dev Reentrancy guard for postIncomingMessages.\n */\n modifier messageInProgressLocker() {\n require(!messageInProgress, \"Message is in progress\");\n messageInProgress = true;\n _;\n messageInProgress = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when IMA is active.\n */\n modifier whenNotPaused(bytes32 schainHash) {\n require(!isPaused(schainHash), \"IMA is paused\");\n _;\n }\n\n /**\n * @dev Allows `msg.sender` to connect schain with MessageProxyOnMainnet for transferring messages.\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n */\n function addConnectedChain(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ISchainsInternal(\n contractManagerOfSkaleManager.getContract(\"SchainsInternal\")\n ).isSchainExist(schainHash), \"SKALE chain must exist\");\n _addConnectedChain(schainHash);\n }\n\n /**\n * @dev Allows owner of the contract to set CommunityPool address for gas reimbursement.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as DEFAULT_ADMIN_ROLE.\n * - Address of CommunityPool contract must not be null.\n */\n function setCommunityPool(ICommunityPool newCommunityPoolAddress) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"Not authorized caller\");\n require(address(newCommunityPoolAddress) != address(0), \"CommunityPool address has to be set\");\n communityPool = newCommunityPoolAddress;\n }\n\n /**\n * @dev Allows `msg.sender` to register extra contract for being able to transfer messages from custom contracts.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function registerExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _registerExtraContract(schainHash, extraContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove extra contract,\n * thus `extraContract` will no longer be available to transfer messages from mainnet to schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE.\n * - Schain name must not be `Mainnet`.\n */\n function removeExtraContract(string memory schainName, address extraContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to register extra contract\"\n );\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n _removeExtraContract(schainHash, extraContract);\n if (_reimbursedContracts[schainHash].contains(extraContract)) {\n _removeReimbursedContract(schainHash, extraContract);\n }\n }\n\n /**\n * @dev Allows `msg.sender` to add reimbursed contract for being able to reimburse gas amount from CommunityPool\n * during message transfers from custom contracts.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n * - `reimbursedContract` should be registered as extra contract\n */\n function addReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\"); \n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to add reimbursed contract\"\n );\n require(reimbursedContract.isContract(), \"Given address is not a contract\");\n require(isContractRegistered(schainHash, reimbursedContract), \"Contract is not registered\");\n require(!_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is already added\");\n _reimbursedContracts[schainHash].add(reimbursedContract);\n emit ReimbursedContractAdded(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Allows `msg.sender` to remove reimbursed contract,\n * thus `reimbursedContract` will no longer be available to reimburse gas amount from CommunityPool during\n * message transfers from mainnet to schain.\n * \n * Requirements:\n * \n * - `msg.sender` must be granted as EXTRA_CONTRACT_REGISTRAR_ROLE or owner of given `schainName`.\n * - Schain name must not be `Mainnet`.\n */\n function removeReimbursedContract(string memory schainName, address reimbursedContract) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(schainHash != MAINNET_HASH, \"Schain hash can not be equal Mainnet\");\n require(\n hasRole(EXTRA_CONTRACT_REGISTRAR_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to remove reimbursed contract\"\n );\n require(_reimbursedContracts[schainHash].contains(reimbursedContract), \"Reimbursed contract is not added\");\n _removeReimbursedContract(schainHash, reimbursedContract);\n }\n\n /**\n * @dev Posts incoming message from `fromSchainName`.\n *\n * Requirements:\n *\n * - `msg.sender` must be authorized caller.\n * - `fromSchainName` must be initialized.\n * - `startingCounter` must be equal to the chain's incoming message counter.\n * - If destination chain is Mainnet, message signature must be valid.\n */\n function postIncomingMessages(\n string calldata fromSchainName,\n uint256 startingCounter,\n Message[] calldata messages,\n Signature calldata sign\n )\n external\n override(IMessageProxy, MessageProxy)\n messageInProgressLocker\n whenNotPaused(keccak256(abi.encodePacked(fromSchainName)))\n {\n uint256 gasTotal = gasleft();\n bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));\n require(isAgentAuthorized(fromSchainHash, msg.sender), \"Agent is not authorized\");\n require(_checkSchainBalance(fromSchainHash), \"Schain wallet has not enough funds\");\n require(connectedChains[fromSchainHash].inited, \"Chain is not initialized\");\n require(messages.length <= MESSAGES_LENGTH, \"Too many messages\");\n require(\n startingCounter == connectedChains[fromSchainHash].incomingMessageCounter,\n \"Starting counter is not equal to incoming message counter\");\n\n require(_verifyMessages(\n fromSchainName,\n _hashedArray(messages, startingCounter, fromSchainName), sign),\n \"Signature is not verified\");\n uint additionalGasPerMessage =\n (gasTotal - gasleft() + headerMessageGasCost + messages.length * messageGasCost) / messages.length;\n uint notReimbursedGas = 0;\n connectedChains[fromSchainHash].incomingMessageCounter += messages.length;\n for (uint256 i = 0; i < messages.length; i++) {\n gasTotal = gasleft();\n if (isReimbursedContract(fromSchainHash, messages[i].destinationContract)) {\n address receiver = _getGasPayer(fromSchainHash, messages[i], startingCounter + i);\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += communityPool.refundGasByUser(\n fromSchainHash,\n payable(msg.sender),\n receiver,\n gasTotal - gasleft() + additionalGasPerMessage\n );\n } else {\n _callReceiverContract(fromSchainHash, messages[i], startingCounter + i);\n notReimbursedGas += gasTotal - gasleft() + additionalGasPerMessage;\n }\n }\n communityPool.refundGasBySchainWallet(fromSchainHash, payable(msg.sender), notReimbursedGas);\n }\n\n /**\n * @dev Sets headerMessageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewHeaderMessageGasCost(uint256 newHeaderMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageHeaderWasChanged(headerMessageGasCost, newHeaderMessageGasCost);\n headerMessageGasCost = newHeaderMessageGasCost;\n }\n\n /**\n * @dev Sets messageGasCost to a new value.\n *\n * Requirements:\n *\n * - `msg.sender` must be granted as CONSTANT_SETTER_ROLE.\n */\n function setNewMessageGasCost(uint256 newMessageGasCost) external override onlyConstantSetter {\n emit GasCostMessageWasChanged(messageGasCost, newMessageGasCost);\n messageGasCost = newMessageGasCost;\n }\n\n /**\n * @dev Sets new version of contracts on mainnet\n *\n * Requirements:\n *\n * - `msg.sender` must be granted DEFAULT_ADMIN_ROLE.\n */\n function setVersion(string calldata newVersion) external override {\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \"DEFAULT_ADMIN_ROLE is required\");\n emit VersionUpdated(version, newVersion);\n version = newVersion;\n }\n\n /**\n * @dev Allows PAUSABLE_ROLE to pause IMA bridge unlimited\n *\n * Requirements:\n *\n * - IMA bridge to current schain was not paused\n * - Sender should be PAUSABLE_ROLE\n */\n function pause(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(PAUSABLE_ROLE, msg.sender), \"Incorrect sender\");\n require(!pauseInfo[schainHash].paused, \"Already paused\");\n pauseInfo[schainHash].paused = true;\n emit SchainPaused(schainHash);\n }\n\n/**\n * @dev Allows DEFAULT_ADMIN_ROLE or schain owner to resume IMA bridge\n *\n * Requirements:\n *\n * - IMA bridge to current schain was paused\n * - Sender should be DEFAULT_ADMIN_ROLE or schain owner\n */\n function resume(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash), \"Incorrect sender\");\n require(pauseInfo[schainHash].paused, \"Already unpaused\");\n pauseInfo[schainHash].paused = false;\n emit SchainResumed(schainHash);\n }\n\n /**\n * @dev Should return length of reimbursed contracts by schainHash.\n */\n function getReimbursedContractsLength(bytes32 schainHash) external view override returns (uint256) {\n return _reimbursedContracts[schainHash].length();\n }\n\n /**\n * @dev Should return a range of reimbursed contracts by schainHash.\n * \n * Requirements:\n * range should be less or equal 10 contracts\n */\n function getReimbursedContractsRange(\n bytes32 schainHash,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory contractsInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _reimbursedContracts[schainHash].length(),\n \"Range is incorrect\"\n );\n contractsInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n contractsInRange[i - from] = _reimbursedContracts[schainHash].at(i);\n }\n }\n\n /**\n * @dev Creates a new MessageProxyForMainnet contract.\n */\n function initialize(IContractManager contractManagerOfSkaleManagerValue) public virtual override initializer {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n MessageProxy.initializeMessageProxy(1e6);\n headerMessageGasCost = 92251;\n messageGasCost = 9000;\n }\n\n /**\n * @dev PostOutgoingMessage function with whenNotPaused modifier\n */\n function postOutgoingMessage(\n bytes32 targetChainHash,\n address targetContract,\n bytes memory data\n )\n public\n override(IMessageProxy, MessageProxy)\n whenNotPaused(targetChainHash)\n {\n super.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n /**\n * @dev Checks whether chain is currently connected.\n *\n * Note: Mainnet chain does not have a public key, and is implicitly\n * connected to MessageProxy.\n *\n * Requirements:\n *\n * - `schainName` must not be Mainnet.\n */\n function isConnectedChain(\n string memory schainName\n )\n public\n view\n override(IMessageProxy, MessageProxy)\n returns (bool)\n {\n require(keccak256(abi.encodePacked(schainName)) != MAINNET_HASH, \"Schain id can not be equal Mainnet\");\n return super.isConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if IMA to schain is paused.\n */\n function isPaused(bytes32 schainHash) public view override returns (bool) {\n return pauseInfo[schainHash].paused;\n }\n\n /**\n * @dev Returns true if message to the contract should be reimbursed from CommunityPool.\n */\n function isReimbursedContract(bytes32 schainHash, address contractAddress) public view override returns (bool) {\n return\n isContractRegistered(bytes32(0), contractAddress) ||\n _reimbursedContracts[schainHash].contains(contractAddress);\n }\n\n // private\n\n function _authorizeOutgoingMessageSender(bytes32 targetChainHash) internal view override {\n require(\n isContractRegistered(bytes32(0), msg.sender)\n || isContractRegistered(targetChainHash, msg.sender)\n || isSchainOwner(msg.sender, targetChainHash),\n \"Sender contract is not registered\"\n );\n }\n\n /**\n * @dev Converts calldata structure to memory structure and checks\n * whether message BLS signature is valid.\n */\n function _verifyMessages(\n string calldata fromSchainName,\n bytes32 hashedMessages,\n MessageProxyForMainnet.Signature calldata sign\n )\n internal\n view\n returns (bool)\n {\n return ISchains(\n contractManagerOfSkaleManager.getContract(\"Schains\")\n ).verifySchainSignature(\n sign.blsSignature[0],\n sign.blsSignature[1],\n hashedMessages,\n sign.counter,\n sign.hashA,\n sign.hashB,\n fromSchainName\n );\n }\n\n /**\n * @dev Checks whether balance of schain wallet is sufficient for\n * for reimbursement custom message.\n */\n function _checkSchainBalance(bytes32 schainHash) internal view returns (bool) {\n return IWallets(\n payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))\n ).getSchainBalance(schainHash) >= (MESSAGES_LENGTH + 1) * gasLimit * tx.gasprice;\n }\n\n /**\n * @dev Returns list of registered custom extra contracts.\n */\n function _getRegistryContracts()\n internal\n view\n override\n returns (mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) storage)\n {\n return _registryContracts;\n }\n\n\n function _removeReimbursedContract(bytes32 schainHash, address reimbursedContract) private {\n _reimbursedContracts[schainHash].remove(reimbursedContract);\n emit ReimbursedContractRemoved(schainHash, reimbursedContract);\n }\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/IWallets.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n IWallets - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface IWallets {\n /**\n * @dev Emitted when the validator wallet was funded\n */\n event ValidatorWalletRecharged(address sponsor, uint amount, uint validatorId);\n\n /**\n * @dev Emitted when the schain wallet was funded\n */\n event SchainWalletRecharged(address sponsor, uint amount, bytes32 schainHash);\n\n /**\n * @dev Emitted when the node received a refund from validator to its wallet\n */\n event NodeRefundedByValidator(address node, uint validatorId, uint amount);\n\n /**\n * @dev Emitted when the node received a refund from schain to its wallet\n */\n event NodeRefundedBySchain(address node, bytes32 schainHash, uint amount);\n\n /**\n * @dev Emitted when the validator withdrawn funds from validator wallet\n */\n event WithdrawFromValidatorWallet(uint indexed validatorId, uint amount);\n\n /**\n * @dev Emitted when the schain owner withdrawn funds from schain wallet\n */\n event WithdrawFromSchainWallet(bytes32 indexed schainHash, uint amount);\n\n receive() external payable;\n function refundGasByValidator(uint validatorId, address payable spender, uint spentGas) external;\n function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;\n function refundGasBySchain(bytes32 schainId, address payable spender, uint spentGas, bool isDebt) external;\n function withdrawFundsFromSchainWallet(address payable schainOwner, bytes32 schainHash) external;\n function withdrawFundsFromValidatorWallet(uint amount) external;\n function rechargeValidatorWallet(uint validatorId) external payable;\n function rechargeSchainWallet(bytes32 schainId) external payable;\n function getSchainBalance(bytes32 schainHash) external view returns (uint);\n function getValidatorBalance(uint validatorId) external view returns (uint);\n}\n" + }, + "@skalenetwork/skale-manager-interfaces/ISchains.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchains.sol - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchains {\n\n struct SchainOption {\n string name;\n bytes value;\n }\n \n /**\n * @dev Emitted when an schain is created.\n */\n event SchainCreated(\n string name,\n address owner,\n uint partOfNode,\n uint lifetime,\n uint numberOfNodes,\n uint deposit,\n uint16 nonce,\n bytes32 schainHash\n );\n\n /**\n * @dev Emitted when an schain is deleted.\n */\n event SchainDeleted(\n address owner,\n string name,\n bytes32 indexed schainHash\n );\n\n /**\n * @dev Emitted when a node in an schain is rotated.\n */\n event NodeRotated(\n bytes32 schainHash,\n uint oldNode,\n uint newNode\n );\n\n /**\n * @dev Emitted when a node is added to an schain.\n */\n event NodeAdded(\n bytes32 schainHash,\n uint newNode\n );\n\n /**\n * @dev Emitted when a group of nodes is created for an schain.\n */\n event SchainNodes(\n string name,\n bytes32 schainHash,\n uint[] nodesInGroup\n );\n\n function addSchain(address from, uint deposit, bytes calldata data) external;\n function addSchainByFoundation(\n uint lifetime,\n uint8 typeOfSchain,\n uint16 nonce,\n string calldata name,\n address schainOwner,\n address schainOriginator,\n SchainOption[] calldata options\n )\n external\n payable;\n function deleteSchain(address from, string calldata name) external;\n function deleteSchainByRoot(string calldata name) external;\n function restartSchainCreation(string calldata name) external;\n function verifySchainSignature(\n uint256 signA,\n uint256 signB,\n bytes32 hash,\n uint256 counter,\n uint256 hashA,\n uint256 hashB,\n string calldata schainName\n )\n external\n view\n returns (bool);\n function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);\n function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);\n function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);\n}" + }, + "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n ISchainsInternal - SKALE Manager Interfaces\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaeiv\n\n SKALE Manager Interfaces is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager Interfaces is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager Interfaces. If not, see .\n*/\n\npragma solidity >=0.6.10 <0.9.0;\n\ninterface ISchainsInternal {\n struct Schain {\n string name;\n address owner;\n uint indexInOwnerList;\n uint8 partOfNode;\n uint lifetime;\n uint startDate;\n uint startBlock;\n uint deposit;\n uint64 index;\n uint generation;\n address originator;\n }\n\n struct SchainType {\n uint8 partOfNode;\n uint numberOfNodes;\n }\n\n /**\n * @dev Emitted when schain type added.\n */\n event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);\n\n /**\n * @dev Emitted when schain type removed.\n */\n event SchainTypeRemoved(uint indexed schainType);\n\n function initializeSchain(\n string calldata name,\n address from,\n address originator,\n uint lifetime,\n uint deposit) external;\n function createGroupForSchain(\n bytes32 schainHash,\n uint numberOfNodes,\n uint8 partOfNode\n )\n external\n returns (uint[] memory);\n function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;\n function removeSchain(bytes32 schainHash, address from) external;\n function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;\n function deleteGroup(bytes32 schainHash) external;\n function setException(bytes32 schainHash, uint nodeIndex) external;\n function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;\n function removeHolesForSchain(bytes32 schainHash) external;\n function addSchainType(uint8 partOfNode, uint numberOfNodes) external;\n function removeSchainType(uint typeOfSchain) external;\n function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;\n function removeNodeFromAllExceptionSchains(uint nodeIndex) external;\n function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;\n function makeSchainNodesInvisible(bytes32 schainHash) external;\n function makeSchainNodesVisible(bytes32 schainHash) external;\n function newGeneration() external;\n function addSchainForNode(uint nodeIndex, bytes32 schainHash) external;\n function removeSchainForNode(uint nodeIndex, uint schainIndex) external;\n function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;\n function isSchainActive(bytes32 schainHash) external view returns (bool);\n function schainsAtSystem(uint index) external view returns (bytes32);\n function numberOfSchains() external view returns (uint64);\n function getSchains() external view returns (bytes32[] memory);\n function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);\n function getSchainListSize(address from) external view returns (uint);\n function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);\n function getSchainIdsByAddress(address from) external view returns (bytes32[] memory);\n function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainIdsForNode(uint nodeIndex) external view returns (bytes32[] memory);\n function getSchainOwner(bytes32 schainHash) external view returns (address);\n function getSchainOriginator(bytes32 schainHash) external view returns (address);\n function isSchainNameAvailable(string calldata name) external view returns (bool);\n function isTimeExpired(bytes32 schainHash) external view returns (bool);\n function isOwnerAddress(address from, bytes32 schainId) external view returns (bool);\n function getSchainName(bytes32 schainHash) external view returns (string memory);\n function getActiveSchain(uint nodeIndex) external view returns (bytes32);\n function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);\n function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);\n function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);\n function isNodeAddressesInGroup(bytes32 schainId, address sender) external view returns (bool);\n function getNodeIndexInGroup(bytes32 schainHash, uint nodeId) external view returns (uint);\n function isAnyFreeNode(bytes32 schainHash) external view returns (bool);\n function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);\n function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);\n function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);\n function getSchainType(uint typeOfSchain) external view returns(uint8, uint);\n function getGeneration(bytes32 schainHash) external view returns (uint);\n function isSchainExist(bytes32 schainHash) external view returns (bool);\n}" + }, + "contracts/mainnet/SkaleManagerClient.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * SkaleManagerClient.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IContractManager.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol\";\n\n\n/**\n * @title SkaleManagerClient - contract that knows ContractManager\n * and makes calls to SkaleManager contracts.\n */\ncontract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable, ISkaleManagerClient {\n\n IContractManager public contractManagerOfSkaleManager;\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwner(string memory schainName) {\n require(\n isSchainOwner(msg.sender, _schainHash(schainName)),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev Modifier for checking whether caller is owner of SKALE chain.\n */\n modifier onlySchainOwnerByHash(bytes32 schainHash) {\n require(\n isSchainOwner(msg.sender, schainHash),\n \"Sender is not an Schain owner\"\n );\n _;\n }\n\n /**\n * @dev initialize - sets current address of ContractManager of SkaleManager.\n * @param newContractManagerOfSkaleManager - current address of ContractManager of SkaleManager.\n */\n function initialize(\n IContractManager newContractManagerOfSkaleManager\n )\n public\n override\n virtual\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n contractManagerOfSkaleManager = newContractManagerOfSkaleManager;\n }\n\n /**\n * @dev Checks whether sender is owner of SKALE chain\n */\n function isSchainOwner(address sender, bytes32 schainHash) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);\n }\n\n function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {\n address skaleChainsInternal = contractManagerOfSkaleManager.getContract(\"SchainsInternal\");\n return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);\n }\n\n function _schainHash(string memory schainName) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(schainName));\n }\n}\n" + }, + "contracts/mainnet/CommunityPool.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n CommunityPool.sol - SKALE Manager\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n @author Artem Payvin\n @author Vadim Yavorsky\n\n SKALE Manager is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE Manager is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE Manager. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol\";\nimport \"@skalenetwork/skale-manager-interfaces/IWallets.sol\";\n\nimport \"../Messages.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title CommunityPool\n * @dev Contract contains logic to perform automatic self-recharging ETH for nodes.\n */\ncontract CommunityPool is Twin, ICommunityPool {\n\n using AddressUpgradeable for address payable;\n\n bytes32 public constant CONSTANT_SETTER_ROLE = keccak256(\"CONSTANT_SETTER_ROLE\");\n\n // address of user => schainHash => balance of gas wallet in ETH\n mapping(address => mapping(bytes32 => uint)) private _userWallets;\n\n // address of user => schainHash => true if unlocked for transferring\n mapping(address => mapping(bytes32 => bool)) public activeUsers;\n\n uint public minTransactionGas;\n\n uint public multiplierNumerator;\n uint public multiplierDivider;\n\n /**\n * @dev Emitted when minimal value in gas for transactions from schain to mainnet was changed \n */\n event MinTransactionGasWasChanged(\n uint oldValue,\n uint newValue\n );\n\n /**\n * @dev Emitted when basefee multiplier was changed \n */\n event MultiplierWasChanged(\n uint oldMultiplierNumerator,\n uint oldMultiplierDivider,\n uint newMultiplierNumerator,\n uint newMultiplierDivider\n );\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linker,\n IMessageProxyForMainnet messageProxyValue\n )\n external\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(linker));\n minTransactionGas = 1e6;\n multiplierNumerator = 3;\n multiplierDivider = 2;\n }\n\n /**\n * @dev Allows MessageProxyForMainnet to reimburse gas for transactions \n * that transfer funds from schain to mainnet.\n * \n * Requirements:\n * \n * - User that receives funds should have enough funds in their gas wallet.\n * - Address that should be reimbursed for executing transaction must not be null.\n */\n function refundGasByUser(\n bytes32 schainHash,\n address payable node,\n address user,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (uint)\n {\n require(node != address(0), \"Node address must be set\");\n if (!activeUsers[user][schainHash]) {\n return gas;\n }\n uint amount = tx.gasprice * gas;\n if (amount > _userWallets[user][schainHash]) {\n amount = _userWallets[user][schainHash];\n }\n _userWallets[user][schainHash] = _userWallets[user][schainHash] - amount;\n if (!_balanceIsSufficient(schainHash, user, 0)) {\n activeUsers[user][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(user)\n );\n }\n node.sendValue(amount);\n return (tx.gasprice * gas - amount) / tx.gasprice;\n }\n\n function refundGasBySchainWallet(\n bytes32 schainHash,\n address payable node,\n uint gas\n )\n external\n override\n onlyMessageProxy\n returns (bool)\n {\n if (gas > 0) {\n\n IWallets(payable(contractManagerOfSkaleManager.getContract(\"Wallets\"))).refundGasBySchain(\n schainHash,\n node,\n gas,\n false\n );\n }\n return true;\n }\n\n /**\n * @dev Allows `msg.sender` to recharge their wallet for further gas reimbursement.\n * \n * Requirements:\n * \n * - 'msg.sender` should recharge their gas wallet for amount that enough to reimburse any \n * transaction from schain to mainnet.\n */\n function rechargeUserWallet(string calldata schainName, address user) external payable override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n _balanceIsSufficient(schainHash, user, msg.value),\n \"Not enough ETH for transaction\"\n );\n _userWallets[user][schainHash] = _userWallets[user][schainHash] + msg.value;\n if (!activeUsers[user][schainHash]) {\n activeUsers[user][schainHash] = true;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeActivateUserMessage(user)\n );\n }\n }\n\n /**\n * @dev Allows `msg.sender` to withdraw funds from their gas wallet.\n * If `msg.sender` withdraws too much funds,\n * then he will no longer be able to transfer their tokens on ETH from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function withdrawFunds(string calldata schainName, uint amount) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(amount <= _userWallets[msg.sender][schainHash], \"Balance is too low\");\n require(!messageProxy.messageInProgress(), \"Message is in progress\");\n _userWallets[msg.sender][schainHash] = _userWallets[msg.sender][schainHash] - amount;\n if (\n !_balanceIsSufficient(schainHash, msg.sender, 0) &&\n activeUsers[msg.sender][schainHash]\n ) {\n activeUsers[msg.sender][schainHash] = false;\n messageProxy.postOutgoingMessage(\n schainHash,\n getSchainContract(schainHash),\n Messages.encodeLockUserMessage(msg.sender)\n );\n }\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMinTransactionGas(uint newMinTransactionGas) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n emit MinTransactionGasWasChanged(minTransactionGas, newMinTransactionGas);\n minTransactionGas = newMinTransactionGas;\n }\n\n /**\n * @dev Allows `msg.sender` set the amount of gas that should be \n * enough for reimbursing any transaction from schain to mainnet.\n * \n * Requirements:\n * \n * - 'msg.sender` must have sufficient amount of ETH on their gas wallet.\n */\n function setMultiplier(uint newMultiplierNumerator, uint newMultiplierDivider) external override {\n require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), \"CONSTANT_SETTER_ROLE is required\");\n require(newMultiplierDivider > 0, \"Divider is zero\");\n emit MultiplierWasChanged(\n multiplierNumerator,\n multiplierDivider,\n newMultiplierNumerator,\n newMultiplierDivider\n );\n multiplierNumerator = newMultiplierNumerator;\n multiplierDivider = newMultiplierDivider;\n }\n\n /**\n * @dev Returns the amount of ETH on gas wallet for particular user.\n */\n function getBalance(address user, string calldata schainName) external view override returns (uint) {\n return _userWallets[user][keccak256(abi.encodePacked(schainName))];\n }\n\n /**\n * @dev Checks whether user is active and wallet was recharged for sufficient amount.\n */\n function checkUserBalance(bytes32 schainHash, address receiver) external view override returns (bool) {\n return activeUsers[receiver][schainHash] && _balanceIsSufficient(schainHash, receiver, 0);\n }\n\n /**\n * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.\n */\n function getRecommendedRechargeAmount(\n bytes32 schainHash,\n address receiver\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 currentValue = _multiplyOnAdaptedBaseFee(minTransactionGas);\n if (currentValue <= _userWallets[receiver][schainHash]) {\n return 0;\n }\n return currentValue - _userWallets[receiver][schainHash];\n }\n\n /**\n * @dev Checks whether user wallet was recharged for sufficient amount.\n */\n function _balanceIsSufficient(bytes32 schainHash, address receiver, uint256 delta) private view returns (bool) {\n return delta + _userWallets[receiver][schainHash] >= minTransactionGas * tx.gasprice;\n }\n\n function _multiplyOnAdaptedBaseFee(uint256 value) private view returns (uint256) {\n return value * block.basefee * multiplierNumerator / multiplierDivider;\n }\n}\n" + }, + "contracts/mainnet/Twin.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Twin.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n * @author Vadim Yavorsky\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/ITwin.sol\";\n\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./SkaleManagerClient.sol\";\n\n/**\n * @title Twin\n * @dev Runs on Mainnet,\n * contains logic for connecting paired contracts on Mainnet and on Schain.\n */\nabstract contract Twin is SkaleManagerClient, ITwin {\n\n IMessageProxyForMainnet public messageProxy;\n mapping(bytes32 => address) public schainLinks;\n bytes32 public constant LINKER_ROLE = keccak256(\"LINKER_ROLE\");\n\n /**\n * @dev Modifier for checking whether caller is MessageProxy contract.\n */\n modifier onlyMessageProxy() {\n require(msg.sender == address(messageProxy), \"Sender is not a MessageProxy\");\n _;\n }\n\n /**\n * @dev Binds a contract on mainnet with their twin on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must not already be added.\n * - Address of contract on schain must be non-zero.\n */\n function addSchainContract(string calldata schainName, address contractReceiver) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] == address(0), \"SKALE chain is already set\");\n require(contractReceiver != address(0), \"Incorrect address of contract receiver on Schain\");\n schainLinks[schainHash] = contractReceiver;\n }\n\n /**\n * @dev Removes connection with contract on schain.\n *\n * Requirements:\n *\n * - `msg.sender` must be schain owner or has required role.\n * - SKALE chain must already be set.\n */\n function removeSchainContract(string calldata schainName) external override {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(\n hasRole(LINKER_ROLE, msg.sender) ||\n isSchainOwner(msg.sender, schainHash), \"Not authorized caller\"\n );\n require(schainLinks[schainHash] != address(0), \"SKALE chain is not set\");\n delete schainLinks[schainHash];\n }\n\n /**\n * @dev Returns true if mainnet contract and schain contract are connected together for transferring messages.\n */\n function hasSchainContract(string calldata schainName) external view override returns (bool) {\n return schainLinks[keccak256(abi.encodePacked(schainName))] != address(0);\n }\n \n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet newMessageProxy\n )\n public\n virtual\n initializer\n {\n SkaleManagerClient.initialize(contractManagerOfSkaleManagerValue);\n messageProxy = newMessageProxy;\n }\n\n function getSchainContract(bytes32 schainHash) public override view returns (address) {\n require(\n schainLinks[schainHash] != address(0),\n \"Destination contract must be defined\"\n );\n return schainLinks[schainHash];\n }\n}\n" + }, + "contracts/test/MessageProxyForMainnetTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\n\n\ninterface IMessageProxyForMainnetTester {\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n ) external;\n}\n\n\ncontract MessageProxyForMainnetTester is MessageProxyForMainnet, IMessageProxyForMainnetTester { \n\n function refundGasByUser(\n bytes32 fromSchainHash,\n address payable node,\n address user,\n uint256 gas\n )\n external\n override\n {\n communityPool.refundGasByUser(fromSchainHash, node, user, gas);\n }\n}\n" + }, + "contracts/test/MessageProxyCaller.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyCaller.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../mainnet/MessageProxyForMainnet.sol\";\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyCaller {\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n ) external;\n}\n\n\ncontract MessageProxyCaller is IMessageProxyCaller { \n\n function postOutgoingMessageTester(\n MessageProxyForMainnet messageProxyForMainnet,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForMainnet.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n\n function postOutgoingMessageTesterOnSchain(\n MessageProxyForSchain messageProxyForSchain,\n bytes32 targetChainHash,\n address targetContract,\n bytes calldata data\n )\n external\n override\n {\n messageProxyForSchain.postOutgoingMessage(targetChainHash, targetContract, data);\n }\n}" + }, + "contracts/test/MessageProxyForSchainTester.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainTester.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"../schain/MessageProxyForSchain.sol\";\n\n\ninterface IMessageProxyForSchainTester {\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external;\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external;\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external;\n}\n\n\ncontract MessageProxyForSchainTester is MessageProxyForSchain, IMessageProxyForSchainTester { \n\n IEtherbaseUpgradeable public etherbase = ETHERBASE;\n\n constructor(IKeyStorage _keyStorage, string memory schainName) {\n MessageProxyForSchain.initialize(_keyStorage, schainName);\n }\n\n function postMessage(\n IMessageReceiver targetContract,\n bytes32 fromSchainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postMessage(fromSchainHash, sender, data);\n }\n\n function postOutgoingMessageTester(\n MessageProxyForSchain targetContract,\n bytes32 targetChainHash,\n address dstContract,\n bytes calldata data\n )\n external\n override\n {\n targetContract.postOutgoingMessage(targetChainHash, dstContract, data);\n }\n\n function setEtherbase(IEtherbaseUpgradeable etherbaseAddress) external override {\n etherbase = etherbaseAddress;\n }\n\n function _getEtherbase() internal view override returns (IEtherbaseUpgradeable) {\n return etherbase;\n }\n}" + }, + "contracts/test/MessageProxyForSchainWithoutSignature.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"./MessageProxyForSchainTester.sol\";\n\ncontract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {\n\n constructor(string memory schainName) MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)\n // solhint-disable-next-line no-empty-blocks\n {}\n\n function _verifyMessages(\n bytes32,\n Signature calldata\n )\n internal\n pure\n override\n returns (bool)\n {\n return true;\n }\n}\n" + }, + "contracts/mainnet/Linker.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * Linker.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/ILinker.sol\";\n\nimport \"../Messages.sol\";\nimport \"./MessageProxyForMainnet.sol\";\nimport \"./Twin.sol\";\n\n\n/**\n * @title Linker For Mainnet\n * @dev Runs on Mainnet,\n * links contracts on mainnet with their twin on schain,\n * allows to kill schain when interchain connection was not enabled.\n */\ncontract Linker is Twin, ILinker {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n enum KillProcess {NotKilled, PartiallyKilledBySchainOwner, PartiallyKilledByContractOwner, Killed}\n EnumerableSetUpgradeable.AddressSet private _mainnetContracts;\n\n // Deprecated variable\n mapping(bytes32 => bool) private _interchainConnections;\n //\n\n // schainHash => schain status of killing process \n mapping(bytes32 => KillProcess) public statuses;\n\n /**\n * @dev Modifier to make a function callable only if caller is granted with {LINKER_ROLE}.\n */\n modifier onlyLinker() {\n require(hasRole(LINKER_ROLE, msg.sender), \"Linker role is required\");\n _;\n }\n\n /**\n * @dev Allows Linker to register external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be not registered.\n */\n function registerMainnetContract(address newMainnetContract) external override onlyLinker {\n require(_mainnetContracts.add(newMainnetContract), \"The contracts was not registered\");\n }\n\n /**\n * @dev Allows Linker to remove external mainnet contracts.\n * \n * Requirements:\n * \n * - Contract must be registered.\n */\n function removeMainnetContract(address mainnetContract) external override onlyLinker {\n require(_mainnetContracts.remove(mainnetContract), \"The contract was not removed\");\n }\n\n /**\n * @dev Allows Linker to connect mainnet contracts with their receivers on schain.\n * \n * Requirements:\n * \n * - Numbers of mainnet contracts and schain contracts must be equal.\n * - Mainnet contract must implement method `addSchainContract`.\n */\n function connectSchain(\n string calldata schainName,\n address[] calldata schainContracts\n )\n external\n override\n onlyLinker\n {\n require(schainContracts.length == _mainnetContracts.length(), \"Incorrect number of addresses\");\n for (uint i = 0; i < schainContracts.length; i++) {\n Twin(_mainnetContracts.at(i)).addSchainContract(schainName, schainContracts[i]);\n }\n messageProxy.addConnectedChain(schainName);\n }\n\n /**\n * @dev Allows Schain owner and contract deployer to kill schain. \n * To kill the schain, both entities must call this function, and the order is not important.\n * \n * Requirements:\n * \n * - Interchain connection should be turned off.\n */\n function kill(string calldata schainName) override external {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n if (statuses[schainHash] == KillProcess.NotKilled) {\n if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {\n statuses[schainHash] = KillProcess.PartiallyKilledByContractOwner;\n } else if (isSchainOwner(msg.sender, schainHash)) {\n statuses[schainHash] = KillProcess.PartiallyKilledBySchainOwner;\n } else {\n revert(\"Not allowed\");\n }\n } else if (\n (\n statuses[schainHash] == KillProcess.PartiallyKilledBySchainOwner &&\n hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) || (\n statuses[schainHash] == KillProcess.PartiallyKilledByContractOwner &&\n isSchainOwner(msg.sender, schainHash)\n )\n ) {\n statuses[schainHash] = KillProcess.Killed;\n } else {\n revert(\"Already killed or incorrect sender\");\n }\n }\n\n /**\n * @dev Allows Linker disconnect schain from the network. This will remove all receiver contracts on schain.\n * Thus, messages will not go from the mainnet to the schain.\n * \n * Requirements:\n * \n * - Mainnet contract should implement method `removeSchainContract`.\n */\n function disconnectSchain(string calldata schainName) external override onlyLinker {\n uint length = _mainnetContracts.length();\n for (uint i = 0; i < length; i++) {\n Twin(_mainnetContracts.at(i)).removeSchainContract(schainName);\n }\n messageProxy.removeConnectedChain(schainName);\n }\n\n /**\n * @dev Returns true if schain is not killed.\n */\n function isNotKilled(bytes32 schainHash) external view override returns (bool) {\n return statuses[schainHash] != KillProcess.Killed;\n }\n\n /**\n * @dev Returns true if list of mainnet contracts has particular contract.\n */\n function hasMainnetContract(address mainnetContract) external view override returns (bool) {\n return _mainnetContracts.contains(mainnetContract);\n }\n\n /**\n * @dev Returns true if mainnet contracts and schain contracts are connected together for transferring messages.\n */\n function hasSchain(string calldata schainName) external view override returns (bool connected) {\n uint length = _mainnetContracts.length();\n connected = messageProxy.isConnectedChain(schainName);\n for (uint i = 0; connected && i < length; i++) {\n connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName);\n }\n }\n\n /**\n * @dev Create a new Linker contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, msg.sender);\n _setupRole(LINKER_ROLE, address(this));\n\n // fake usage of variable\n delete _interchainConnections[bytes32(0)];\n }\n}\n" + }, + "contracts/mainnet/DepositBox.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBox.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol\";\n\nimport \"./Twin.sol\";\n\n\n/**\n * @title DepositBox\n * @dev Abstract contracts for DepositBoxes on mainnet.\n */\nabstract contract DepositBox is IDepositBox, Twin {\n\n ILinker public linker;\n\n // schainHash => true if automatic deployment tokens on schain was enabled \n mapping(bytes32 => bool) private _automaticDeploy;\n\n bytes32 public constant DEPOSIT_BOX_MANAGER_ROLE = keccak256(\"DEPOSIT_BOX_MANAGER_ROLE\");\n\n /**\n * @dev Modifier for checking whether schain was not killed.\n */\n modifier whenNotKilled(bytes32 schainHash) {\n require(linker.isNotKilled(schainHash), \"Schain is killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schain was killed.\n */\n modifier whenKilled(bytes32 schainHash) {\n require(!linker.isNotKilled(schainHash), \"Schain is not killed\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainName is not equal to `Mainnet` \n * and address of receiver is not equal to null before transferring funds from mainnet to schain.\n */\n modifier rightTransaction(string memory schainName, address to) {\n require(\n keccak256(abi.encodePacked(schainName)) != keccak256(abi.encodePacked(\"Mainnet\")),\n \"SKALE chain name cannot be Mainnet\"\n );\n require(to != address(0), \"Receiver address cannot be null\");\n _;\n }\n\n /**\n * @dev Modifier for checking whether schainHash is not equal to `Mainnet` \n * and sender contract was added as contract processor on schain.\n */\n modifier checkReceiverChain(bytes32 schainHash, address sender) {\n require(\n schainHash != keccak256(abi.encodePacked(\"Mainnet\")) &&\n sender == schainLinks[schainHash],\n \"Receiver chain is incorrect\"\n );\n _;\n }\n\n /**\n * @dev Allows Schain owner turn on whitelist of tokens.\n */\n function enableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = false;\n }\n\n /**\n * @dev Allows Schain owner turn off whitelist of tokens.\n */\n function disableWhitelist(string memory schainName) external override onlySchainOwner(schainName) {\n _automaticDeploy[keccak256(abi.encodePacked(schainName))] = true;\n }\n\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker newLinker,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override\n virtual\n initializer\n {\n Twin.initialize(contractManagerOfSkaleManagerValue, messageProxyValue);\n _setupRole(LINKER_ROLE, address(newLinker));\n linker = newLinker;\n }\n\n /**\n * @dev Returns is whitelist enabled on schain.\n */\n function isWhitelisted(string memory schainName) public view override returns (bool) {\n return !_automaticDeploy[keccak256(abi.encodePacked(schainName))];\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxEth.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxEth.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxEth\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ETH.\n */\ncontract DepositBoxEth is DepositBox, IDepositBoxEth {\n using AddressUpgradeable for address payable;\n\n mapping(address => uint256) public approveTransfers;\n\n mapping(bytes32 => uint256) public transferredAmount;\n\n mapping(bytes32 => bool) public activeEthTransfers;\n\n event ActiveEthTransfers(bytes32 indexed schainHash, bool active);\n\n receive() external payable override {\n revert(\"Use deposit function\");\n }\n\n /**\n * @dev Allows `msg.sender` to send ETH from mainnet to schain.\n * \n * Requirements:\n * \n * - Schain name must not be `Mainnet`.\n * - Receiver contract should be added as twin contract on schain.\n * - Schain that receives tokens should not be killed.\n */\n function deposit(string memory schainName)\n external\n payable\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n _saveTransferredAmount(schainHash, msg.value);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n Messages.encodeTransferEthMessage(msg.sender, msg.value)\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the eth came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of eth on DepositBoxEth should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n require(\n message.amount <= address(this).balance,\n \"Not enough money to finish this transaction\"\n );\n _removeTransferredAmount(schainHash, message.amount);\n if (!activeEthTransfers[schainHash]) {\n approveTransfers[message.receiver] += message.amount;\n } else {\n payable(message.receiver).sendValue(message.amount);\n }\n }\n\n /**\n * @dev Transfers a user's ETH.\n *\n * Requirements:\n *\n * - DepositBoxETh must have sufficient ETH.\n * - User must be approved for ETH transfer.\n */\n function getMyEth() external override {\n require(approveTransfers[msg.sender] > 0, \"User has insufficient ETH\");\n uint256 amount = approveTransfers[msg.sender];\n approveTransfers[msg.sender] = 0;\n payable(msg.sender).sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to return each user their ETH.\n *\n * Requirements:\n *\n * - Amount of ETH on schain should be equal or more than transferred amount.\n * - Receiver address must not be null.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address payable receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n require(receiver != address(0), \"Receiver address has to be set\");\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[schainHash] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, amount);\n receiver.sendValue(amount);\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function enableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(!activeEthTransfers[schainHash], \"Active eth transfers enabled\");\n emit ActiveEthTransfers(schainHash, true);\n activeEthTransfers[schainHash] = true;\n }\n\n /**\n * @dev Allows Schain owner to switch on or switch off active eth transfers.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function disableActiveEthTransfers(string calldata schainName)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(activeEthTransfers[schainHash], \"Active eth transfers disabled\");\n emit ActiveEthTransfers(schainHash, false);\n activeEthTransfers[schainHash] = false;\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferEthMessage memory message = Messages.decodeTransferEthMessage(data);\n return message.receiver;\n }\n\n /**\n * @dev Creates a new DepositBoxEth contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Saves amount of ETH that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] += amount;\n }\n\n /**\n * @dev Removes amount of ETH that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, uint256 amount) private {\n transferredAmount[schainHash] -= amount;\n }\n}\n" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC721\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721 is DepositBox, IDepositBoxERC721 {\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC721;\n mapping(address => mapping(uint256 => bytes32)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC721.\n */\n event ERC721TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC721TokenReady(address indexed contractOnMainnet, uint256 tokenId);\n\n /**\n * @dev Allows `msg.sender` to send ERC721 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their token for DepositBoxERC721 address.\n */\n function depositERC721(\n string calldata schainName,\n address erc721OnMainnet,\n uint256 tokenId\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC721Upgradeable(erc721OnMainnet).getApproved(tokenId) == address(this),\n \"DepositBox was not approved for ERC721 token\"\n );\n bytes memory data = _receiveERC721(\n schainName,\n erc721OnMainnet,\n msg.sender,\n tokenId\n );\n _saveTransferredAmount(schainHash, erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(msg.sender, address(this), tokenId);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n virtual\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(IERC721Upgradeable(message.token).ownerOf(message.tokenId) == address(this), \"Incorrect tokenId\");\n _removeTransferredAmount(message.token, message.tokenId);\n IERC721Upgradeable(message.token).transferFrom(address(this), message.receiver, message.tokenId);\n }\n\n /**\n * @dev Allows Schain owner to add an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC721ForSchain(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - DepositBoxERC721 contract should own such token.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(transferredAmount[erc721OnMainnet][tokenId] == schainHash, \"Incorrect tokenId\");\n _removeTransferredAmount(erc721OnMainnet, tokenId);\n IERC721Upgradeable(erc721OnMainnet).transferFrom(address(this), receiver, tokenId);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n virtual\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC721[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC721[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC721 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * automatically added after sending to schain if whitelist was turned off.\n */\n function getSchainToERC721(\n string calldata schainName,\n address erc721OnMainnet\n )\n public\n view\n override\n returns (bool)\n {\n return _schainToERC721[keccak256(abi.encodePacked(schainName))].contains(erc721OnMainnet);\n }\n\n /**\n * @dev Removes the ids of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(address erc721Token, uint256 tokenId) internal {\n transferredAmount[erc721Token][tokenId] = bytes32(0);\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n virtual\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC721AddedToSchain = _schainToERC721[schainHash].contains(erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721AndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721Message(erc721OnMainnet, to, tokenId);\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Adds an ERC721 token to DepositBoxERC721.\n * \n * Emits an {ERC721TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC721ForSchain(string calldata schainName, address erc721OnMainnet) internal {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc721OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC721[schainHash].contains(erc721OnMainnet), \"ERC721 Token was already added\");\n _schainToERC721[schainHash].add(erc721OnMainnet);\n emit ERC721TokenAdded(schainName, erc721OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC721 token such as token name, symbol.\n */\n function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {\n return Messages.Erc721TokenInfo({\n name: erc721.name(),\n symbol: erc721.symbol()\n });\n }\n\n /**\n * @dev Saves the ids of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc721Token, uint256 tokenId) private {\n transferredAmount[erc721Token][tokenId] = schainHash;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC721.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC721 is IDepositBox {\n function depositERC721(string calldata schainName, address erc721OnMainnet, uint256 tokenId) external;\n function addERC721TokenByOwner(string calldata schainName, address erc721OnMainnet) external;\n function getFunds(string calldata schainName, address erc721OnMainnet, address receiver, uint tokenId) external;\n function getSchainToERC721(string calldata schainName, address erc721OnMainnet) external view returns (bool);\n function getSchainToAllERC721Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC721(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC721WithMetadata.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"./DepositBoxERC721.sol\";\nimport \"../../Messages.sol\";\n\n/**\n * @title DepositBoxERC721WithMetadata\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC721.\n */\ncontract DepositBoxERC721WithMetadata is DepositBoxERC721 {\n using AddressUpgradeable for address;\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC721 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - DepositBoxERC721 contract should own token.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n require(message.erc721message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC721Upgradeable(message.erc721message.token).ownerOf(message.erc721message.tokenId) == address(this),\n \"Incorrect tokenId\"\n );\n _removeTransferredAmount(message.erc721message.token, message.erc721message.tokenId);\n IERC721Upgradeable(message.erc721message.token).transferFrom(\n address(this),\n message.erc721message.receiver,\n message.erc721message.tokenId\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc721MessageWithMetadata memory message =\n Messages.decodeTransferErc721MessageWithMetadata(data);\n return message.erc721message.receiver;\n }\n\n /**\n * @dev Allows DepositBoxERC721 to receive ERC721 tokens.\n * \n * Emits an {ERC721TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.\n */\n function _receiveERC721(\n string calldata schainName,\n address erc721OnMainnet,\n address to,\n uint256 tokenId\n )\n internal\n override\n returns (bytes memory data)\n {\n bool isERC721AddedToSchain = getSchainToERC721(schainName, erc721OnMainnet);\n if (!isERC721AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC721ForSchain(schainName, erc721OnMainnet);\n data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId),\n _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc721MessageWithMetadata(\n erc721OnMainnet,\n to,\n tokenId,\n _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainnet), tokenId)\n );\n }\n emit ERC721TokenReady(erc721OnMainnet, tokenId);\n }\n\n /**\n * @dev Returns tokenURI of ERC721 token.\n */\n function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {\n return erc721.tokenURI(tokenId);\n }\n\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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 *\n * NOTE: 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 *\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 ) external 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.\n *\n * NOTE: 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 *\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 ) external returns (bytes4);\n}\n" + }, + "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\nabstract contract ERC1155ReceiverUpgradeableWithoutGap is\n Initializable,\n ERC165Upgradeable,\n IERC1155ReceiverUpgradeable\n{\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // solhint-disable-next-line func-name-mixedcase\n function __ERC1155Receiver_init() internal initializer {\n __ERC165_init_unchained();\n __ERC1155Receiver_init_unchained();\n }\n\n // solhint-disable-next-line func-name-mixedcase, no-empty-blocks\n function __ERC1155Receiver_init_unchained() internal initializer {\n }\n}" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 * @dev See {_setURI}.\n */\n function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\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) public 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: address zero is not a valid owner\");\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(address[] memory accounts, uint256[] memory ids)\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 _setApprovalForAll(_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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeTransferFrom(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 ) public virtual override {\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n _safeBatchTransferFrom(from, to, ids, amounts, data);\n }\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 * - `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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n }\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 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function _safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\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 uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n _balances[id][to] += amount;\n }\n\n emit TransferBatch(operator, from, to, ids, amounts);\n\n _afterTokenTransfer(operator, from, to, ids, amounts, data);\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 `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal virtual {\n require(to != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _balances[id][to] += amount;\n emit TransferSingle(operator, address(0), to, id, amount);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\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 _mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) 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 (uint256 i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] += amounts[i];\n }\n\n emit TransferBatch(operator, address(0), to, ids, amounts);\n\n _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n }\n\n /**\n * @dev Destroys `amount` tokens of token type `id` from `from`\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `from` must have at least `amount` tokens of token type `id`.\n */\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n uint256[] memory ids = _asSingletonArray(id);\n uint256[] memory amounts = _asSingletonArray(amount);\n\n _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n\n emit TransferSingle(operator, from, address(0), id, amount);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n */\n function _burnBatch(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal virtual {\n require(from != 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, from, address(0), ids, amounts, \"\");\n\n for (uint256 i = 0; i < ids.length; i++) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n uint256 fromBalance = _balances[id][from];\n require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n unchecked {\n _balances[id][from] = fromBalance - amount;\n }\n }\n\n emit TransferBatch(operator, from, address(0), ids, amounts);\n\n _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC1155: setting approval status for self\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\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 `ids` and `amounts` 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 ) internal virtual {}\n\n /**\n * @dev Hook that is called after 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 _afterTokenTransfer(\n address operator,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal virtual {}\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 ) private {\n if (to.isContract()) {\n try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\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)\n external\n view\n 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 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(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) 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(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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/schain/TokenManagers/TokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * TokenManager.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../tokens/ERC1155OnChain.sol\";\nimport \"../TokenManager.sol\";\nimport \"../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol\";\n\n\n/**\n * @title TokenManagerERC1155\n * @dev Runs on SKALE Chains,\n * accepts messages from mainnet,\n * and creates ERC1155 clones.\n * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.\n */\ncontract TokenManagerERC1155 is\n TokenManager,\n ERC1155ReceiverUpgradeableWithoutGap,\n ITokenManagerERC1155\n{\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n // address of ERC1155 on Mainnet => ERC1155 on Schain\n mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;\n\n // address clone on schain => added or not\n mapping(ERC1155OnChain => bool) public addedClones;\n\n mapping(bytes32 => mapping(address => ERC1155OnChain)) public clonesErc1155;\n\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when schain owner register new ERC1155 clone.\n */\n event ERC1155TokenAdded(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.\n */\n event ERC1155TokenCreated(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain\n );\n\n /**\n * @dev Emitted when someone sends tokens from mainnet to schain.\n */\n event ERC1155TokenReceived(\n bytes32 indexed chainHash,\n address indexed erc1155OnMainnet,\n address indexed erc1155OnSchain,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Emitted when token is received by TokenManager and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(\n bytes32 indexed chainHash,\n address indexed contractOnMainnet,\n uint256[] ids,\n uint256[] amounts\n );\n\n /**\n * @dev Move tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to mainnet.\n * \n * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.\n */\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n {\n communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);\n _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Move tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);\n }\n\n /**\n * @dev Move batch of tokens from schain to schain.\n * \n * {contractOnMainnet} tokens are burned on origin schain\n * and are minted on {targetSchainName} schain for {to} address.\n */\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) \n external\n override\n rightTransaction(targetSchainName, msg.sender)\n {\n bytes32 targetSchainHash = keccak256(abi.encodePacked(targetSchainName));\n communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);\n _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);\n }\n\n /**\n * @dev Allows MessageProxy to post operational message from mainnet\n * or SKALE chains.\n *\n * Requirements:\n * \n * - MessageProxy must be the sender.\n * - `fromChainHash` must exist in TokenManagerERC1155 addresses.\n */\n function postMessage(\n bytes32 fromChainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n checkReceiverChain(fromChainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n address receiver = address(0);\n if (\n operation == Messages.MessageType.TRANSFER_ERC1155 ||\n operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155(fromChainHash, data);\n } else if (\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||\n operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO\n ) {\n receiver = _sendERC1155Batch(fromChainHash, data);\n } else {\n revert(\"MessageType is unknown\");\n }\n }\n\n /**\n * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.\n */\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n )\n external\n override\n onlyTokenRegistrar\n {\n require(messageProxy.isConnectedChain(targetChainName), \"Chain is not connected\");\n require(erc1155OnSchain.isContract(), \"Given address is not a contract\");\n bytes32 targetChainHash = keccak256(abi.encodePacked(targetChainName));\n require(address(clonesErc1155[targetChainHash][erc1155OnMainnet]) == address(0), \"Could not relink clone\");\n require(!addedClones[ERC1155OnChain(erc1155OnSchain)], \"Clone was already added\");\n clonesErc1155[targetChainHash][erc1155OnMainnet] = ERC1155OnChain(erc1155OnSchain);\n addedClones[ERC1155OnChain(erc1155OnSchain)] = true;\n emit ERC1155TokenAdded(targetChainHash, erc1155OnMainnet, erc1155OnSchain);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(\n string memory newChainName,\n IMessageProxyForSchain newMessageProxy,\n ITokenManagerLinker newIMALinker,\n ICommunityLocker newCommunityLocker,\n address newDepositBox\n )\n external\n override\n initializer\n {\n TokenManager.initializeTokenManager(\n newChainName,\n newMessageProxy,\n newIMALinker,\n newCommunityLocker,\n newDepositBox\n );\n }\n\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)\n returns (bool)\n {\n return interfaceId == type(TokenManager).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n\n /**\n * @dev Allows TokenManager to send ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256 id;\n uint256 amount;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155){\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n receiver = message.receiver;\n token = message.token;\n id = message.id;\n amount = message.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155AndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155AndTokenInfoMessage(data);\n receiver = message.baseErc1155transfer.receiver;\n token = message.baseErc1155transfer.token;\n id = message.baseErc1155transfer.id;\n amount = message.baseErc1155transfer.amount;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n addedClones[contractOnSchain] = true;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155 &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, \"\");\n } else {\n contractOnSchain.mint(receiver, id, amount, \"\");\n }\n emit ERC1155TokenReceived(\n fromChainHash,\n token,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n return receiver;\n }\n\n /**\n * @dev Allows TokenManager to send a batch of ERC1155 tokens.\n * \n * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.\n * Emits a {ERC20TokenReceived} event on success.\n */\n function _sendERC1155Batch(bytes32 fromChainHash, bytes calldata data) private returns (address) {\n Messages.MessageType messageType = Messages.getMessageType(data);\n address receiver;\n address token;\n uint256[] memory ids;\n uint256[] memory amounts;\n ERC1155OnChain contractOnSchain;\n if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n receiver = message.receiver;\n token = message.token;\n ids = message.ids;\n amounts = message.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n } else {\n Messages.TransferErc1155BatchAndTokenInfoMessage memory message =\n Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);\n receiver = message.baseErc1155Batchtransfer.receiver;\n token = message.baseErc1155Batchtransfer.token;\n ids = message.baseErc1155Batchtransfer.ids;\n amounts = message.baseErc1155Batchtransfer.amounts;\n contractOnSchain = clonesErc1155[fromChainHash][token];\n if (address(contractOnSchain) == address(0)) {\n require(automaticDeploy, \"Automatic deploy is disabled\");\n contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);\n clonesErc1155[fromChainHash][token] = contractOnSchain;\n emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));\n }\n }\n if (\n messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&\n fromChainHash != MAINNET_HASH &&\n _schainToERC1155[fromChainHash].contains(token)\n ) {\n require(token.isContract(), \"Incorrect main chain token\");\n _removeTransferredAmount(fromChainHash, token, ids, amounts);\n IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, \"\");\n } else {\n contractOnSchain.mintBatch(receiver, ids, amounts, \"\");\n }\n emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);\n return receiver;\n }\n\n /**\n * @dev Burn tokens on schain and send message to unlock them on target chain.\n */\n function _exit(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(\n chainHash,\n address(contractOnSchain),\n _asSingletonArray(id),\n _asSingletonArray(amount)\n );\n contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n } else {\n contractOnSchain.burn(msg.sender, id, amount);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Burn batch of tokens on schain and send message to unlock them on target chain.\n */\n function _exitBatch(\n bytes32 chainHash,\n address messageReceiver,\n address contractOnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n {\n bool isMainChainToken;\n ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];\n if (address(contractOnSchain) == address(0)) {\n contractOnSchain = ERC1155OnChain(contractOnMainChain);\n require(!addedClones[contractOnSchain], \"Incorrect main chain token\");\n isMainChainToken = true;\n }\n require(address(contractOnSchain).isContract(), \"No token clone on schain\");\n require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), \"Not allowed ERC1155 Token\");\n bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);\n if (isMainChainToken) {\n require(chainHash != MAINNET_HASH, \"Main chain token could not be transfered to Mainnet\");\n data = _receiveERC1155Batch(\n chainHash,\n address(contractOnSchain),\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);\n contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n } else {\n contractOnSchain.burnBatch(msg.sender, ids, amounts);\n }\n messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 chainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);\n }\n \n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n bytes32 chainHash,\n address erc1155OnMainChain,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);\n if (!isERC1155AddedToSchain) {\n _addERC1155ForSchain(chainHash, erc1155OnMainChain);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainChain,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);\n }\n emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(bytes32 chainHash, address erc1155OnMainChain) private {\n require(erc1155OnMainChain.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), \"ERC1155 Token was already added\");\n _schainToERC1155[chainHash].add(erc1155OnMainChain);\n emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Create array with single element in it.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ITokenManagerERC1155 - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"./ITokenContractManager.sol\";\n\n\ninterface ITokenManagerERC1155 is ITokenContractManager {\n function exitToMainERC1155(\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function exitToMainERC1155Batch(\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function transferToSchainERC1155(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256 id,\n uint256 amount\n ) external;\n function transferToSchainERC1155Batch(\n string calldata targetSchainName,\n address contractOnMainnet,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function addERC1155TokenByOwner(\n string calldata targetChainName,\n address erc1155OnMainnet,\n address erc1155OnSchain\n ) external;\n}" + }, + "contracts/schain/tokens/ERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * ERC1155OnChain.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol\";\n\n\n/**\n * @title ERC1155OnChain\n * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.\n */\ncontract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n constructor(\n string memory uri\n ) initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC1155Upgradeable.__ERC1155_init(uri);\n ERC1155BurnableUpgradeable.__ERC1155Burnable_init();\n\n _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);\n _setupRole(MINTER_ROLE, _msgSender());\n }\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mint(account, id, amount, data);\n }\n\n /**\n * @dev Mint batch of tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n )\n external\n override\n {\n require(hasRole(MINTER_ROLE, _msgSender()), \"Sender is not a Minter\");\n _mintBatch(account, ids, amounts, data);\n }\n\n /**\n * @dev Check if contract support {interfaceId} interface.\n * \n * See https://eips.ethereum.org/EIPS/eip-165 for more details.\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.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 ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(\n address account,\n uint256 id,\n uint256 value\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory values\n ) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner nor approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IERC1155OnChain - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\n\ninterface IERC1155OnChain {\n function mint(\n address account,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external;\n function mintBatch(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external;\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol\";\n\nimport \"../DepositBox.sol\";\nimport \"../../Messages.sol\";\n\n\n/**\n * @title DepositBoxERC1155\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC1155.\n */\ncontract DepositBoxERC1155 is DepositBox, ERC1155ReceiverUpgradeable, IDepositBoxERC1155 {\n\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n\n // schainHash => address of ERC on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC1155;\n mapping(bytes32 => mapping(address => mapping(uint256 => uint256))) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC1155TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC1155TokenReady(address indexed contractOnMainnet, uint256[] ids, uint256[] amounts);\n\n /**\n * @dev Allows `msg.sender` to send ERC1155 token from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256 id,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token\"\n );\n bytes memory data = _receiveERC1155(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n id,\n amount\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n IERC1155Upgradeable(erc1155OnMainnet).safeTransferFrom(msg.sender, address(this), id, amount, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows `msg.sender` to send batch of ERC1155 tokens from mainnet to schain.\n * \n * Requirements:\n * \n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC1155 address.\n */\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC1155Upgradeable(erc1155OnMainnet).isApprovedForAll(msg.sender, address(this)),\n \"DepositBox was not approved for ERC1155 token Batch\"\n );\n bytes memory data = _receiveERC1155Batch(\n schainName,\n erc1155OnMainnet,\n msg.sender,\n ids,\n amounts\n );\n _saveTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(msg.sender, address(this), ids, amounts, \"\");\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC1155 token from schain to mainnet.\n * \n * Requirements:\n * \n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be added to DepositBoxERC1155 and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC1155 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(\n schainHash,\n message.token,\n _asSingletonArray(message.id),\n _asSingletonArray(message.amount)\n );\n IERC1155Upgradeable(message.token).safeTransferFrom(\n address(this),\n message.receiver,\n message.id,\n message.amount,\n \"\"\n );\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n _removeTransferredAmount(schainHash, message.token, message.ids, message.amounts);\n IERC1155Upgradeable(message.token).safeBatchTransferFrom(\n address(this),\n message.receiver,\n message.ids,\n message.amounts,\n \"\"\n );\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC1155TokenByOwner(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(keccak256(abi.encodePacked(schainName)))\n {\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address, \n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n * \n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n )\n external\n override\n onlySchainOwner(schainName)\n whenKilled(keccak256(abi.encodePacked(schainName)))\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++) {\n require(transferredAmount[schainHash][erc1155OnMainnet][ids[i]] >= amounts[i], \"Incorrect amount\");\n }\n _removeTransferredAmount(schainHash, erc1155OnMainnet, ids, amounts);\n IERC1155Upgradeable(erc1155OnMainnet).safeBatchTransferFrom(\n address(this),\n receiver,\n ids,\n amounts,\n \"\"\n );\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.MessageType operation = Messages.getMessageType(data);\n if (operation == Messages.MessageType.TRANSFER_ERC1155) {\n Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);\n return message.receiver;\n } else if (operation == Messages.MessageType.TRANSFER_ERC1155_BATCH) {\n Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);\n return message.receiver;\n }\n return address(0);\n }\n\n\n /**\n * @dev Returns selector of onERC1155Received.\n */\n function onERC1155Received(\n address operator,\n address,\n uint256,\n uint256,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 transfer\");\n return bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"));\n }\n\n\n /**\n * @dev Returns selector of onERC1155BatchReceived.\n */\n function onERC1155BatchReceived(\n address operator,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n )\n external\n view\n override\n returns(bytes4)\n {\n require(operator == address(this), \"Revert ERC1155 batch transfer\");\n return bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"));\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC1155(\n string calldata schainName,\n address erc1155OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].contains(erc1155OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner \n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC1155[keccak256(abi.encodePacked(schainName))].length();\n }\n\n /**\n * @dev Should return an array of tokens were added by Schain owner or \n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC1155[keccak256(abi.encodePacked(schainName))].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC1155[keccak256(abi.encodePacked(schainName))].at(i);\n }\n }\n\n /**\n * @dev Creates a new DepositBoxERC1155 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue, \n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n __ERC1155Receiver_init();\n }\n\n /**\n * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).\n */\n function supportsInterface(\n bytes4 interfaceId\n )\n public\n view\n override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeable)\n returns (bool)\n {\n return interfaceId == type(Twin).interfaceId\n || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] + amounts[i];\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(\n bytes32 schainHash,\n address erc1155Token,\n uint256[] memory ids,\n uint256[] memory amounts\n ) private {\n require(ids.length == amounts.length, \"Incorrect length of arrays\");\n for (uint256 i = 0; i < ids.length; i++)\n transferredAmount[schainHash][erc1155Token][ids[i]] =\n transferredAmount[schainHash][erc1155Token][ids[i]] - amounts[i];\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256 id,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155AndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n id,\n amount,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155Message(erc1155OnMainnet, to, id, amount);\n }\n \n emit ERC1155TokenReady(erc1155OnMainnet, _asSingletonArray(id), _asSingletonArray(amount));\n }\n\n /**\n * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.\n * \n * Emits an {ERC1155TokenReady} event.\n * \n * Requirements:\n * \n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.\n */\n function _receiveERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n bool isERC1155AddedToSchain = _schainToERC1155[schainHash].contains(erc1155OnMainnet);\n if (!isERC1155AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC1155ForSchain(schainName, erc1155OnMainnet);\n data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(\n erc1155OnMainnet,\n to,\n ids,\n amounts,\n _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainnet))\n );\n } else {\n data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainnet, to, ids, amounts);\n }\n emit ERC1155TokenReady(erc1155OnMainnet, ids, amounts);\n }\n\n /**\n * @dev Adds an ERC1155 token to DepositBoxERC1155.\n * \n * Emits an {ERC1155TokenAdded} event.\n * \n * Requirements:\n * \n * - Given address should be contract.\n */\n function _addERC1155ForSchain(string calldata schainName, address erc1155OnMainnet) private {\n bytes32 schainHash = keccak256(abi.encodePacked(schainName));\n require(erc1155OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC1155[schainHash].contains(erc1155OnMainnet), \"ERC1155 Token was already added\");\n _schainToERC1155[schainHash].add(erc1155OnMainnet);\n emit ERC1155TokenAdded(schainName, erc1155OnMainnet);\n }\n\n /**\n * @dev Returns info about ERC1155 token.\n */\n function _getTokenInfo(\n IERC1155MetadataURIUpgradeable erc1155\n )\n private\n view\n returns (Messages.Erc1155TokenInfo memory)\n {\n return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});\n }\n\n /**\n * @dev Returns array with single element that passed as argument.\n */\n function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {\n array = new uint256[](1);\n array[0] = element;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155ReceiverUpgradeable.sol\";\nimport \"../../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n function __ERC1155Receiver_init() internal onlyInitializing {\n }\n\n function __ERC1155Receiver_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC1155.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC1155 is IDepositBox {\n function depositERC1155(string calldata schainName, address erc1155OnMainnet, uint256 id, uint256 amount) external;\n function depositERC1155Batch(\n string calldata schainName,\n address erc1155OnMainnet,\n uint256[] calldata ids,\n uint256[] calldata amounts\n ) external;\n function addERC1155TokenByOwner(string calldata schainName, address erc1155OnMainnet) external;\n function getFunds(\n string calldata schainName,\n address erc1155OnMainnet,\n address receiver,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n function getSchainToERC1155(string calldata schainName, address erc1155OnMainnet) external view returns (bool);\n function getSchainToAllERC1155Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC1155(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n}" + }, + "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * DepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol\";\n\nimport \"../../Messages.sol\";\nimport \"../DepositBox.sol\";\n\ninterface IERC20TransferVoid {\n function transferFrom(address _from, address _to, uint256 _amount) external;\n function transfer(address _to, uint256 _amount) external;\n}\n\n\n/**\n * @title DepositBoxERC20\n * @dev Runs on mainnet,\n * accepts messages from schain,\n * stores deposits of ERC20.\n */\ncontract DepositBoxERC20 is DepositBox, IDepositBoxERC20 {\n using AddressUpgradeable for address;\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n using SafeERC20Upgradeable for IERC20MetadataUpgradeable;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n enum DelayedTransferStatus {\n DELAYED,\n ARBITRAGE,\n COMPLETED\n }\n\n struct DelayedTransfer {\n address receiver;\n bytes32 schainHash;\n address token;\n uint256 amount;\n uint256 untilTimestamp;\n DelayedTransferStatus status;\n }\n\n struct DelayConfig {\n // token address => value\n mapping(address => uint256) bigTransferThreshold;\n EnumerableSetUpgradeable.AddressSet trustedReceivers;\n uint256 transferDelay;\n uint256 arbitrageDuration;\n }\n\n uint256 private constant _QUEUE_PROCESSING_LIMIT = 10;\n\n bytes32 public constant ARBITER_ROLE = keccak256(\"ARBITER_ROLE\");\n\n // schainHash => address of ERC20 on Mainnet\n // Deprecated\n // slither-disable-next-line unused-state\n mapping(bytes32 => mapping(address => bool)) private _deprecatedSchainToERC20;\n mapping(bytes32 => mapping(address => uint256)) public transferredAmount;\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;\n\n // exits delay configuration\n // schainHash => delay config\n mapping(bytes32 => DelayConfig) private _delayConfig;\n\n uint256 public delayedTransfersSize;\n // delayed transfer id => delayed transfer\n mapping(uint256 => DelayedTransfer) public delayedTransfers;\n // receiver address => delayed transfers ids queue\n mapping(address => DoubleEndedQueueUpgradeable.Bytes32Deque) public delayedTransfersByReceiver;\n\n /**\n * @dev Emitted when token is mapped in DepositBoxERC20.\n */\n event ERC20TokenAdded(string schainName, address indexed contractOnMainnet);\n\n /**\n * @dev Emitted when token is received by DepositBox and is ready to be cloned\n * or transferred on SKALE chain.\n */\n event ERC20TokenReady(address indexed contractOnMainnet, uint256 amount);\n\n event TransferDelayed(uint256 id, address receiver, address token, uint256 amount);\n\n event Escalated(uint256 id);\n\n /**\n * @dev Emitted when token transfer is skipped due to internal token error\n */\n event TransferSkipped(uint256 id);\n\n /**\n * @dev Emitted when big transfer threshold is changed\n */\n event BigTransferThresholdIsChanged(\n bytes32 indexed schainHash,\n address indexed token,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when big transfer delay is changed\n */\n event BigTransferDelayIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Emitted when arbitrage duration is changed\n */\n event ArbitrageDurationIsChanged(\n bytes32 indexed schainHash,\n uint256 oldValue,\n uint256 newValue\n );\n\n /**\n * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain\n *\n * Requirements:\n *\n * - Schain name must not be `Mainnet`.\n * - Receiver account on schain cannot be null.\n * - Schain that receives tokens should not be killed.\n * - Receiver contract should be defined.\n * - `msg.sender` should approve their tokens for DepositBoxERC20 address.\n */\n function depositERC20(\n string calldata schainName,\n address erc20OnMainnet,\n uint256 amount\n )\n external\n override\n rightTransaction(schainName, msg.sender)\n whenNotKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n address contractReceiver = schainLinks[schainHash];\n require(contractReceiver != address(0), \"Unconnected chain\");\n require(\n IERC20MetadataUpgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,\n \"DepositBox was not approved for ERC20 token\"\n );\n bytes memory data = _receiveERC20(\n schainName,\n erc20OnMainnet,\n msg.sender,\n amount\n );\n _saveTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);\n messageProxy.postOutgoingMessage(\n schainHash,\n contractReceiver,\n data\n );\n }\n\n /**\n * @dev Allows MessageProxyForMainnet contract to execute transferring ERC20 token from schain to mainnet.\n *\n * Requirements:\n *\n * - Schain from which the tokens came should not be killed.\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n * - Amount of tokens on DepositBoxERC20 should be equal or more than transferred amount.\n */\n function postMessage(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n override\n onlyMessageProxy\n whenNotKilled(schainHash)\n checkReceiverChain(schainHash, sender)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n require(message.token.isContract(), \"Given address is not a contract\");\n require(\n IERC20MetadataUpgradeable(message.token).balanceOf(address(this)) >= message.amount,\n \"Not enough money\"\n );\n _removeTransferredAmount(schainHash, message.token, message.amount);\n\n uint256 delay = _delayConfig[schainHash].transferDelay;\n if (\n delay > 0\n && _delayConfig[schainHash].bigTransferThreshold[message.token] <= message.amount\n && !isReceiverTrusted(schainHash, message.receiver)\n ) {\n _createDelayedTransfer(schainHash, message, delay);\n } else {\n IERC20MetadataUpgradeable(message.token).safeTransfer(message.receiver, message.amount);\n }\n }\n\n /**\n * @dev Allows Schain owner to add an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Schain should not be killed.\n * - Only owner of the schain able to run function.\n */\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet)\n external\n override\n onlySchainOwner(schainName)\n whenNotKilled(_schainHash(schainName))\n {\n _addERC20ForSchain(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Allows Schain owner to return each user their tokens.\n * The Schain owner decides which tokens to send to which address,\n * since the contract on mainnet does not store information about which tokens belong to whom.\n *\n * Requirements:\n *\n * - Amount of tokens on schain should be equal or more than transferred amount.\n * - msg.sender should be an owner of schain\n * - IMA transfers Mainnet <-> schain should be killed\n */\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount)\n external\n override\n onlySchainOwner(schainName)\n whenKilled(_schainHash(schainName))\n {\n bytes32 schainHash = _schainHash(schainName);\n require(transferredAmount[schainHash][erc20OnMainnet] >= amount, \"Incorrect amount\");\n _removeTransferredAmount(schainHash, erc20OnMainnet, amount);\n IERC20MetadataUpgradeable(erc20OnMainnet).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Set a threshold amount of tokens.\n * If amount of tokens that exits IMA is bigger than the threshold\n * the transfer is delayed for configurable amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferValue(\n string calldata schainName,\n address token,\n uint256 value\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n emit BigTransferThresholdIsChanged(\n schainHash,\n token,\n _delayConfig[schainHash].bigTransferThreshold[token],\n value\n );\n _delayConfig[schainHash].bigTransferThreshold[token] = value;\n }\n\n /**\n * @dev Set a time delay.\n * If amount of tokens that exits IMA is bigger than a threshold\n * the transfer is delayed for set amount of time\n * and can be canceled by a voting\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setBigTransferDelay(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit BigTransferDelayIsChanged(schainHash, _delayConfig[schainHash].transferDelay, delayInSeconds);\n _delayConfig[schainHash].transferDelay = delayInSeconds;\n }\n\n /**\n * @dev Set an arbitrage.\n * After escalation the transfer is locked for provided period of time.\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n */\n function setArbitrageDuration(\n string calldata schainName,\n uint256 delayInSeconds\n )\n external\n override\n onlySchainOwner(schainName)\n {\n bytes32 schainHash = _schainHash(schainName);\n // need to restrict big delays to avoid overflow\n require(delayInSeconds < 1e8, \"Delay is too big\"); // no more then ~ 3 years\n emit ArbitrageDurationIsChanged(schainHash, _delayConfig[schainHash].arbitrageDuration, delayInSeconds);\n _delayConfig[schainHash].arbitrageDuration = delayInSeconds;\n }\n\n /**\n * @dev Add the address to a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must not be in the whitelist\n */\n function trustReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(\n _delayConfig[_schainHash(schainName)].trustedReceivers.add(receiver),\n \"Receiver already is trusted\"\n );\n }\n\n /**\n * @dev Remove the address from a whitelist of addresses that can do big transfers without delaying\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - the address must be in the whitelist\n */\n function stopTrustingReceiver(\n string calldata schainName,\n address receiver\n )\n external\n override\n onlySchainOwner(schainName)\n {\n require(_delayConfig[_schainHash(schainName)].trustedReceivers.remove(receiver), \"Receiver is not trusted\");\n }\n\n /**\n * @dev Transfers tokens that was locked for delay during exit process.\n * Must be called by a receiver.\n */\n function retrieve() external override {\n retrieveFor(msg.sender);\n }\n\n /**\n * @dev Initialize arbitrage of a suspicious big transfer\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain or have ARBITER_ROLE role\n * - transfer must be delayed and arbitrage must not be started\n */\n function escalate(uint256 transferId) external override {\n bytes32 schainHash = delayedTransfers[transferId].schainHash;\n require(\n hasRole(ARBITER_ROLE, msg.sender) || isSchainOwner(msg.sender, schainHash),\n \"Not enough permissions to request escalation\"\n );\n require(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED, \"The transfer has to be delayed\");\n delayedTransfers[transferId].status = DelayedTransferStatus.ARBITRAGE;\n delayedTransfers[transferId].untilTimestamp = MathUpgradeable.max(\n delayedTransfers[transferId].untilTimestamp,\n block.timestamp + _delayConfig[schainHash].arbitrageDuration\n );\n emit Escalated(transferId);\n }\n\n /**\n * @dev Approve a big transfer and immidiately transfer tokens during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function validateTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(transfer.receiver, transfer.amount);\n }\n\n /**\n * @dev Reject a big transfer and transfer tokens to SKALE chain owner during arbitrage\n *\n * Requirements:\n *\n * - msg.sender should be an owner of schain\n * - arbitrage of the transfer must be started\n */\n function rejectTransfer(\n uint transferId\n )\n external\n override\n onlySchainOwnerByHash(delayedTransfers[transferId].schainHash)\n {\n DelayedTransfer storage transfer = delayedTransfers[transferId];\n require(transfer.status == DelayedTransferStatus.ARBITRAGE, \"Arbitrage has to be active\");\n transfer.status = DelayedTransferStatus.COMPLETED;\n delete transfer.untilTimestamp;\n // msg.sender is schain owner\n IERC20MetadataUpgradeable(transfer.token).safeTransfer(msg.sender, transfer.amount);\n }\n\n function doTransfer(address token, address receiver, uint256 amount) external override {\n require(msg.sender == address(this), \"Internal use only\");\n IERC20Upgradeable(token).safeTransfer(receiver, amount);\n }\n\n /**\n * @dev Returns receiver of message.\n *\n * Requirements:\n *\n * - Sender contract should be defined and schain name cannot be `Mainnet`.\n */\n function gasPayer(\n bytes32 schainHash,\n address sender,\n bytes calldata data\n )\n external\n view\n override\n checkReceiverChain(schainHash, sender)\n returns (address)\n {\n Messages.TransferErc20Message memory message = Messages.decodeTransferErc20Message(data);\n return message.receiver;\n }\n\n /**\n * @dev Should return true if token was added by Schain owner or\n * added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToERC20(\n string calldata schainName,\n address erc20OnMainnet\n )\n external\n view\n override\n returns (bool)\n {\n return _schainToERC20[_schainHash(schainName)].contains(erc20OnMainnet);\n }\n\n /**\n * @dev Should return length of a set of all mapped tokens which were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20Length(string calldata schainName) external view override returns (uint256) {\n return _schainToERC20[_schainHash(schainName)].length();\n }\n\n /**\n * @dev Should return an array of range of tokens were added by Schain owner\n * or added automatically after sending to schain if whitelist was turned off.\n */\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n override\n returns (address[] memory tokensInRange)\n {\n require(\n from < to && to - from <= 10 && to <= _schainToERC20[_schainHash(schainName)].length(),\n \"Range is incorrect\"\n );\n tokensInRange = new address[](to - from);\n for (uint256 i = from; i < to; i++) {\n tokensInRange[i - from] = _schainToERC20[_schainHash(schainName)].at(i);\n }\n }\n\n /**\n * @dev Get amount of tokens that are delayed for specified receiver\n */\n function getDelayedAmount(address receiver, address token) external view override returns (uint256 value) {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status == DelayedTransferStatus.DELAYED || status == DelayedTransferStatus.ARBITRAGE) {\n value += transfer.amount;\n }\n }\n }\n }\n\n /**\n * @dev Get timestamp of next unlock of tokens that are delayed for specified receiver\n */\n function getNextUnlockTimestamp(\n address receiver,\n address token\n )\n external\n view\n override\n returns (uint256 unlockTimestamp)\n {\n uint256 delayedTransfersAmount = delayedTransfersByReceiver[receiver].length();\n unlockTimestamp = type(uint256).max;\n for (uint256 i = 0; i < delayedTransfersAmount; ++i) {\n DelayedTransfer storage transfer = delayedTransfers[uint256(delayedTransfersByReceiver[receiver].at(i))];\n DelayedTransferStatus status = transfer.status;\n if (transfer.token == token) {\n if (status != DelayedTransferStatus.COMPLETED) {\n unlockTimestamp = MathUpgradeable.min(unlockTimestamp, transfer.untilTimestamp);\n }\n if (status == DelayedTransferStatus.DELAYED) {\n break;\n }\n }\n }\n }\n\n /**\n * @dev Get amount of addresses that are added to the whitelist\n */\n function getTrustedReceiversAmount(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].trustedReceivers.length();\n }\n\n /**\n * @dev Get i-th address of the whitelist\n */\n function getTrustedReceiver(string calldata schainName, uint256 index) external view override returns (address) {\n return _delayConfig[_schainHash(schainName)].trustedReceivers.at(index);\n }\n\n /**\n * @dev Get amount of tokens that are considered as a big transfer\n */\n function getBigTransferThreshold(bytes32 schainHash, address token) external view override returns (uint256) {\n return _delayConfig[schainHash].bigTransferThreshold[token];\n }\n\n /**\n * @dev Get time delay of big transfers\n */\n function getTimeDelay(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].transferDelay;\n }\n\n /**\n * @dev Get duration of an arbitrage\n */\n function getArbitrageDuration(bytes32 schainHash) external view override returns (uint256) {\n return _delayConfig[schainHash].arbitrageDuration;\n }\n\n /**\n * @dev Retrive tokens that were unlocked after delay for specified receiver\n */\n function retrieveFor(address receiver) public override {\n uint256 transfersAmount = MathUpgradeable.min(\n delayedTransfersByReceiver[receiver].length(),\n _QUEUE_PROCESSING_LIMIT\n );\n\n uint256 currentIndex = 0;\n bool retrieved = false;\n for (uint256 i = 0; i < transfersAmount; ++i) {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex));\n DelayedTransfer memory transfer = delayedTransfers[transferId];\n ++currentIndex;\n\n if (transfer.status != DelayedTransferStatus.COMPLETED) {\n if (block.timestamp < transfer.untilTimestamp) {\n // disable detector untill slither fixes false positive\n // https://github.com/crytic/slither/issues/778\n // slither-disable-next-line incorrect-equality\n if (transfer.status == DelayedTransferStatus.DELAYED) {\n break;\n } else {\n // status is ARBITRAGE\n continue;\n }\n } else {\n // it's time to unlock\n if (currentIndex == 1) {\n --currentIndex;\n _removeOldestDelayedTransfer(receiver);\n } else {\n delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;\n }\n retrieved = true;\n try\n this.doTransfer(transfer.token, transfer.receiver, transfer.amount)\n // solhint-disable-next-line no-empty-blocks\n {}\n catch {\n emit TransferSkipped(transferId);\n }\n }\n } else {\n // status is COMPLETED\n if (currentIndex == 1) {\n --currentIndex;\n retrieved = true;\n _removeOldestDelayedTransfer(receiver);\n }\n }\n }\n require(retrieved, \"There are no transfers available for retrieving\");\n }\n\n /**\n * @dev Creates a new DepositBoxERC20 contract.\n */\n function initialize(\n IContractManager contractManagerOfSkaleManagerValue,\n ILinker linkerValue,\n IMessageProxyForMainnet messageProxyValue\n )\n public\n override(DepositBox, IDepositBox)\n initializer\n {\n DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);\n }\n\n /**\n * @dev Check if the receiver is in the delay whitelist\n */\n function isReceiverTrusted(bytes32 schainHash, address receiver) public view override returns (bool) {\n return _delayConfig[schainHash].trustedReceivers.contains(receiver);\n }\n\n // private\n\n /**\n * @dev Saves amount of tokens that was transferred to schain.\n */\n function _saveTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] += amount;\n }\n\n /**\n * @dev Removes amount of tokens that was transferred from schain.\n */\n function _removeTransferredAmount(bytes32 schainHash, address erc20Token, uint256 amount) private {\n transferredAmount[schainHash][erc20Token] -= amount;\n }\n\n /**\n * @dev Allows DepositBoxERC20 to receive ERC20 tokens.\n *\n * Emits an {ERC20TokenReady} event.\n *\n * Requirements:\n *\n * - Amount must be less than or equal to the total supply of the ERC20 contract.\n * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.\n */\n function _receiveERC20(\n string calldata schainName,\n address erc20OnMainnet,\n address to,\n uint256 amount\n )\n private\n returns (bytes memory data)\n {\n bytes32 schainHash = _schainHash(schainName);\n IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);\n uint256 totalSupply = erc20.totalSupply();\n require(amount <= totalSupply, \"Amount is incorrect\");\n bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);\n if (!isERC20AddedToSchain) {\n require(!isWhitelisted(schainName), \"Whitelist is enabled\");\n _addERC20ForSchain(schainName, erc20OnMainnet);\n data = Messages.encodeTransferErc20AndTokenInfoMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20),\n _getErc20TokenInfo(erc20)\n );\n } else {\n data = Messages.encodeTransferErc20AndTotalSupplyMessage(\n erc20OnMainnet,\n to,\n amount,\n _getErc20TotalSupply(erc20)\n );\n }\n emit ERC20TokenReady(erc20OnMainnet, amount);\n }\n\n /**\n * @dev Adds an ERC20 token to DepositBoxERC20.\n *\n * Emits an {ERC20TokenAdded} event.\n *\n * Requirements:\n *\n * - Given address should be contract.\n */\n function _addERC20ForSchain(string calldata schainName, address erc20OnMainnet) private {\n bytes32 schainHash = _schainHash(schainName);\n require(erc20OnMainnet.isContract(), \"Given address is not a contract\");\n require(!_schainToERC20[schainHash].contains(erc20OnMainnet), \"ERC20 Token was already added\");\n _schainToERC20[schainHash].add(erc20OnMainnet);\n emit ERC20TokenAdded(schainName, erc20OnMainnet);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue\n */\n function _addToDelayedQueue(\n address receiver,\n uint256 id,\n uint256 until\n )\n private\n {\n _addToDelayedQueueWithPriority(delayedTransfersByReceiver[receiver], id, until, _QUEUE_PROCESSING_LIMIT);\n }\n\n /**\n * @dev Add delayed transfer to receiver specific queue at the position\n * that maintains order from earlier unlocked to later unlocked.\n * If the position is located further than depthLimit from the back\n * the element is added at back - depthLimit index\n */\n function _addToDelayedQueueWithPriority(\n DoubleEndedQueueUpgradeable.Bytes32Deque storage queue,\n uint256 id,\n uint256 until,\n uint256 depthLimit\n )\n private\n {\n if (depthLimit == 0 || queue.empty()) {\n queue.pushBack(bytes32(id));\n } else {\n if (delayedTransfers[uint256(queue.back())].untilTimestamp <= until) {\n queue.pushBack(bytes32(id));\n } else {\n bytes32 lowPriorityValue = queue.popBack();\n _addToDelayedQueueWithPriority(queue, id, until, depthLimit - 1);\n queue.pushBack(lowPriorityValue);\n }\n }\n }\n\n /**\n * Create instance of DelayedTransfer and initialize all auxiliary fields.\n */\n function _createDelayedTransfer(\n bytes32 schainHash,\n Messages.TransferErc20Message memory message,\n uint256 delay\n )\n private\n {\n uint256 delayId = delayedTransfersSize++;\n delayedTransfers[delayId] = DelayedTransfer({\n receiver: message.receiver,\n schainHash: schainHash,\n token: message.token,\n amount: message.amount,\n untilTimestamp: block.timestamp + delay,\n status: DelayedTransferStatus.DELAYED\n });\n _addToDelayedQueue(message.receiver, delayId, block.timestamp + delay);\n emit TransferDelayed(delayId, message.receiver, message.token, message.amount);\n }\n\n /**\n * Remove instance of DelayedTransfer and clean auxiliary fields.\n */\n function _removeOldestDelayedTransfer(address receiver) private {\n uint256 transferId = uint256(delayedTransfersByReceiver[receiver].popFront());\n // For most cases the loop will have only 1 iteration.\n // In worst case the amount of iterations is limited by _QUEUE_PROCESSING_LIMIT\n // slither-disable-next-line costly-loop\n delete delayedTransfers[transferId];\n }\n\n /**\n * @dev Returns total supply of ERC20 token.\n */\n function _getErc20TotalSupply(IERC20MetadataUpgradeable erc20Token) private view returns (uint256) {\n return erc20Token.totalSupply();\n }\n\n /**\n * @dev Returns info about ERC20 token such as token name, decimals, symbol.\n */\n function _getErc20TokenInfo(IERC20MetadataUpgradeable erc20Token)\n private\n view\n returns (Messages.Erc20TokenInfo memory)\n {\n return Messages.Erc20TokenInfo({\n name: erc20Token.name(),\n decimals: erc20Token.decimals(),\n symbol: erc20Token.symbol()\n });\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` \u2192 `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * IDepositBoxERC20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2021-Present SKALE Labs\n * @author Dmytro Stebaiev\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity >=0.6.10 <0.9.0;\n\nimport \"../IDepositBox.sol\";\n\n\ninterface IDepositBoxERC20 is IDepositBox {\n function addERC20TokenByOwner(string calldata schainName, address erc20OnMainnet) external;\n function depositERC20(string calldata schainName, address erc20OnMainnet, uint256 amount) external;\n function doTransfer(address token, address receiver, uint256 amount) external;\n function escalate(uint256 transferId) external;\n function getFunds(string calldata schainName, address erc20OnMainnet, address receiver, uint amount) external;\n function rejectTransfer(uint transferId) external;\n function retrieve() external;\n function retrieveFor(address receiver) external;\n function setArbitrageDuration(string calldata schainName, uint256 delayInSeconds) external;\n function setBigTransferValue(string calldata schainName, address token, uint256 value) external;\n function setBigTransferDelay(string calldata schainName, uint256 delayInSeconds) external;\n function stopTrustingReceiver(string calldata schainName, address receiver) external;\n function trustReceiver(string calldata schainName, address receiver) external;\n function validateTransfer(uint transferId) external;\n function isReceiverTrusted(bytes32 schainHash, address receiver) external view returns (bool);\n function getArbitrageDuration(bytes32 schainHash) external view returns (uint256);\n function getBigTransferThreshold(bytes32 schainHash, address token) external view returns (uint256);\n function getDelayedAmount(address receiver, address token) external view returns (uint256 value);\n function getNextUnlockTimestamp(address receiver, address token) external view returns (uint256 unlockTimestamp);\n function getSchainToERC20(string calldata schainName, address erc20OnMainnet) external view returns (bool);\n function getSchainToAllERC20Length(string calldata schainName) external view returns (uint256);\n function getSchainToAllERC20(\n string calldata schainName,\n uint256 from,\n uint256 to\n )\n external\n view\n returns (address[] memory);\n function getTimeDelay(bytes32 schainHash) external view returns (uint256);\n function getTrustedReceiver(string calldata schainName, uint256 index) external view returns (address);\n function getTrustedReceiversAmount(bytes32 schainHash) external view returns (uint256);\n}" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/schain/tokens/EthErc20.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/**\n * EthErc20.sol - SKALE Interchain Messaging Agent\n * Copyright (C) 2019-Present SKALE Labs\n * @author Artem Payvin\n *\n * SKALE IMA is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published\n * by the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * SKALE IMA is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with SKALE IMA. If not, see .\n */\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol\";\n\n\n/**\n * @title EthErc20\n * @dev ERC20 token that represents ETH on mainnet.\n */\ncontract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {\n\n /**\n * @dev id of a role that allows token minting.\n */\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n\n /**\n * @dev id of a role that allows token burning.\n */\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n /**\n * @dev Mint tokens.\n * \n * Requirements:\n * \n * - sender must be granted with {MINTER_ROLE}.\n */\n function mint(address account, uint256 amount) external override {\n require(hasRole(MINTER_ROLE, _msgSender()), \"MINTER role is required\");\n _mint(account, amount);\n }\n\n /**\n * @dev Burn tokens for any account.\n * \n * Requirements:\n * \n * - sender must be granted with {BURNER_ROLE}.\n */\n function forceBurn(address account, uint256 amount) external override {\n require(hasRole(BURNER_ROLE, _msgSender()), \"BURNER role is required\");\n _burn(account, amount);\n }\n\n /**\n * @dev Is called once during contract deployment.\n */\n function initialize(address tokenManagerEthAddress)\n external\n override\n initializer\n {\n AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();\n ERC20Upgradeable.__ERC20_init(\"ERC20 Ether Clone\", \"ETHC\");\n ERC20BurnableUpgradeable.__ERC20Burnable_init(); \n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _setupRole(MINTER_ROLE, tokenManagerEthAddress);\n _setupRole(BURNER_ROLE, tokenManagerEthAddress);\n }\n}\n" + }, + "contracts/test/SafeMock.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\n\n/*\n SafeMock.sol - SKALE Interchain Messaging Agent\n Copyright (C) 2021-Present SKALE Labs\n @author Dmytro Stebaiev\n\n SKALE IMA is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published\n by the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n SKALE IMA is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with SKALE IMA. If not, see .\n*/\n\npragma solidity 0.8.16;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ninterface ISafeMock {\n enum Operation {Call, DelegateCall}\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external;\n function destroy() external;\n function multiSend(bytes memory transactions) external;\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) external view returns (bytes32);\n}\n\ncontract SafeMock is OwnableUpgradeable, ISafeMock {\n\n bool public constant IS_SAFE_MOCK = true;\n bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(\n \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,\"\n \"address gasToken,address refundReceiver,uint256 nonce)\"\n );\n bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(\n \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n );\n\n constructor() initializer {\n OwnableUpgradeable.__Ownable_init();\n multiSend(\"\"); // this is needed to remove slither warning\n }\n\n function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {\n proxyAdmin.transferOwnership(newOwner);\n }\n\n function destroy() external override onlyOwner {\n selfdestruct(payable(msg.sender));\n }\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions) public override\n {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n // solhint-disable-next-line no-empty-blocks\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right \n // since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes])\n // to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte\n // (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas(), to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas(), to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view override returns (bytes32) {\n return keccak256(\n _encodeTransactionData(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution\n /// (e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function _encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) private view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPE_HASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), _domainSeparator(), safeTxHash);\n }\n\n function _domainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPE_HASH, block.chainid, this));\n }\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ], + "": [ + "ast" + ] + } + } + } + } +} \ No newline at end of file diff --git a/proxy/predeployed/src/ima_predeployed/contract_generator.py b/predeployed/src/ima_predeployed/contract_generator.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contract_generator.py rename to predeployed/src/ima_predeployed/contract_generator.py diff --git a/predeployed/src/ima_predeployed/contracts/__init__.py b/predeployed/src/ima_predeployed/contracts/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/predeployed/src/ima_predeployed/contracts/admin_upgradeability_proxy.py b/predeployed/src/ima_predeployed/contracts/admin_upgradeability_proxy.py new file mode 100644 index 000000000..efa80dbe4 --- /dev/null +++ b/predeployed/src/ima_predeployed/contracts/admin_upgradeability_proxy.py @@ -0,0 +1,17 @@ +from ..contract_generator import ContractGenerator + + +class AdminUpgradeabilityProxyGenerator(ContractGenerator): + ARTIFACT_FILENAME = "AdminUpgradeabilityProxy.json" + IMPLEMENTATION_SLOT = int('0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc', 16) + ADMIN_SLOT = int('0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103', 16) + + def __init__(self, logic_address: str, admin_address: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup(logic_address, admin_address) + + # private + + def _setup(self, logic_address: str, admin_address: str) -> None: + self._write_address(self.IMPLEMENTATION_SLOT, logic_address) + self._write_address(self.ADMIN_SLOT, admin_address) diff --git a/proxy/predeployed/src/ima_predeployed/contracts/community_locker.py b/predeployed/src/ima_predeployed/contracts/community_locker.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/community_locker.py rename to predeployed/src/ima_predeployed/contracts/community_locker.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/erc1155_on_chain.py b/predeployed/src/ima_predeployed/contracts/erc1155_on_chain.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/erc1155_on_chain.py rename to predeployed/src/ima_predeployed/contracts/erc1155_on_chain.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/erc20_on_chain.py b/predeployed/src/ima_predeployed/contracts/erc20_on_chain.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/erc20_on_chain.py rename to predeployed/src/ima_predeployed/contracts/erc20_on_chain.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/erc721_on_chain.py b/predeployed/src/ima_predeployed/contracts/erc721_on_chain.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/erc721_on_chain.py rename to predeployed/src/ima_predeployed/contracts/erc721_on_chain.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/eth_erc20.py b/predeployed/src/ima_predeployed/contracts/eth_erc20.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/eth_erc20.py rename to predeployed/src/ima_predeployed/contracts/eth_erc20.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/key_storage.py b/predeployed/src/ima_predeployed/contracts/key_storage.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/key_storage.py rename to predeployed/src/ima_predeployed/contracts/key_storage.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/message_proxy_for_schain.py b/predeployed/src/ima_predeployed/contracts/message_proxy_for_schain.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/message_proxy_for_schain.py rename to predeployed/src/ima_predeployed/contracts/message_proxy_for_schain.py diff --git a/predeployed/src/ima_predeployed/contracts/proxy_admin.py b/predeployed/src/ima_predeployed/contracts/proxy_admin.py new file mode 100644 index 000000000..cc5898c37 --- /dev/null +++ b/predeployed/src/ima_predeployed/contracts/proxy_admin.py @@ -0,0 +1,14 @@ +from ..contract_generator import ContractGenerator + + +class ProxyAdminGenerator(ContractGenerator): + ARTIFACT_FILENAME = "ProxyAdmin.json" + + def __init__(self, owner_address: str): + super().__init__(self.ARTIFACT_FILENAME) + self._setup(owner_address) + + # private + + def _setup(self, owner_address: str) -> None: + self._write_address(0, owner_address) diff --git a/proxy/predeployed/src/ima_predeployed/contracts/token_manager.py b/predeployed/src/ima_predeployed/contracts/token_manager.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/token_manager.py rename to predeployed/src/ima_predeployed/contracts/token_manager.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc1155.py b/predeployed/src/ima_predeployed/contracts/token_manager_erc1155.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc1155.py rename to predeployed/src/ima_predeployed/contracts/token_manager_erc1155.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc20.py b/predeployed/src/ima_predeployed/contracts/token_manager_erc20.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc20.py rename to predeployed/src/ima_predeployed/contracts/token_manager_erc20.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc721.py b/predeployed/src/ima_predeployed/contracts/token_manager_erc721.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc721.py rename to predeployed/src/ima_predeployed/contracts/token_manager_erc721.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc721_with_metadata.py b/predeployed/src/ima_predeployed/contracts/token_manager_erc721_with_metadata.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/token_manager_erc721_with_metadata.py rename to predeployed/src/ima_predeployed/contracts/token_manager_erc721_with_metadata.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/token_manager_eth.py b/predeployed/src/ima_predeployed/contracts/token_manager_eth.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/token_manager_eth.py rename to predeployed/src/ima_predeployed/contracts/token_manager_eth.py diff --git a/proxy/predeployed/src/ima_predeployed/contracts/token_manager_linker.py b/predeployed/src/ima_predeployed/contracts/token_manager_linker.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/contracts/token_manager_linker.py rename to predeployed/src/ima_predeployed/contracts/token_manager_linker.py diff --git a/proxy/predeployed/src/ima_predeployed/generator.py b/predeployed/src/ima_predeployed/generator.py similarity index 100% rename from proxy/predeployed/src/ima_predeployed/generator.py rename to predeployed/src/ima_predeployed/generator.py diff --git a/predeployed/src/ima_predeployed/upgradeable_contract_generator.py b/predeployed/src/ima_predeployed/upgradeable_contract_generator.py new file mode 100644 index 000000000..7465fed12 --- /dev/null +++ b/predeployed/src/ima_predeployed/upgradeable_contract_generator.py @@ -0,0 +1,13 @@ +from .contract_generator import ContractGenerator +from .contracts.admin_upgradeability_proxy import AdminUpgradeabilityProxyGenerator + + +class UpgradeableContractGenerator(AdminUpgradeabilityProxyGenerator): + def __init__(self, implementation_address: str, proxy_admin_address, implementation_generator: ContractGenerator): + super().__init__(implementation_address, proxy_admin_address) + self.implementation_generator = implementation_generator + + def generate_contract(self, balance: int = 0, nonce: int = 0) -> dict: + contract = super().generate_contract(balance, nonce) + contract['storage'].update(self.implementation_generator.generate_contract(balance, nonce)['storage']) + return contract diff --git a/proxy/predeployed/test/base_genesis.json b/predeployed/test/base_genesis.json similarity index 100% rename from proxy/predeployed/test/base_genesis.json rename to predeployed/test/base_genesis.json diff --git a/proxy/predeployed/test/config.json b/predeployed/test/config.json similarity index 100% rename from proxy/predeployed/test/config.json rename to predeployed/test/config.json diff --git a/proxy/predeployed/test/contracts/admin_upgradeability_proxy.py b/predeployed/test/contracts/admin_upgradeability_proxy.py similarity index 100% rename from proxy/predeployed/test/contracts/admin_upgradeability_proxy.py rename to predeployed/test/contracts/admin_upgradeability_proxy.py diff --git a/proxy/predeployed/test/contracts/community_locker.py b/predeployed/test/contracts/community_locker.py similarity index 100% rename from proxy/predeployed/test/contracts/community_locker.py rename to predeployed/test/contracts/community_locker.py diff --git a/proxy/predeployed/test/contracts/eth_erc20.py b/predeployed/test/contracts/eth_erc20.py similarity index 100% rename from proxy/predeployed/test/contracts/eth_erc20.py rename to predeployed/test/contracts/eth_erc20.py diff --git a/proxy/predeployed/test/contracts/key_storage.py b/predeployed/test/contracts/key_storage.py similarity index 100% rename from proxy/predeployed/test/contracts/key_storage.py rename to predeployed/test/contracts/key_storage.py diff --git a/proxy/predeployed/test/contracts/message_proxy_for_schain.py b/predeployed/test/contracts/message_proxy_for_schain.py similarity index 100% rename from proxy/predeployed/test/contracts/message_proxy_for_schain.py rename to predeployed/test/contracts/message_proxy_for_schain.py diff --git a/proxy/predeployed/test/contracts/token_manager_erc1155.py b/predeployed/test/contracts/token_manager_erc1155.py similarity index 100% rename from proxy/predeployed/test/contracts/token_manager_erc1155.py rename to predeployed/test/contracts/token_manager_erc1155.py diff --git a/proxy/predeployed/test/contracts/token_manager_erc20.py b/predeployed/test/contracts/token_manager_erc20.py similarity index 100% rename from proxy/predeployed/test/contracts/token_manager_erc20.py rename to predeployed/test/contracts/token_manager_erc20.py diff --git a/proxy/predeployed/test/contracts/token_manager_erc721.py b/predeployed/test/contracts/token_manager_erc721.py similarity index 100% rename from proxy/predeployed/test/contracts/token_manager_erc721.py rename to predeployed/test/contracts/token_manager_erc721.py diff --git a/proxy/predeployed/test/contracts/token_manager_erc721_with_metadata.py b/predeployed/test/contracts/token_manager_erc721_with_metadata.py similarity index 100% rename from proxy/predeployed/test/contracts/token_manager_erc721_with_metadata.py rename to predeployed/test/contracts/token_manager_erc721_with_metadata.py diff --git a/proxy/predeployed/test/contracts/token_manager_eth.py b/predeployed/test/contracts/token_manager_eth.py similarity index 100% rename from proxy/predeployed/test/contracts/token_manager_eth.py rename to predeployed/test/contracts/token_manager_eth.py diff --git a/proxy/predeployed/test/contracts/token_manager_linker.py b/predeployed/test/contracts/token_manager_linker.py similarity index 100% rename from proxy/predeployed/test/contracts/token_manager_linker.py rename to predeployed/test/contracts/token_manager_linker.py diff --git a/proxy/predeployed/test/generate_genesis.py b/predeployed/test/generate_genesis.py similarity index 100% rename from proxy/predeployed/test/generate_genesis.py rename to predeployed/test/generate_genesis.py diff --git a/predeployed/test/genesis.json b/predeployed/test/genesis.json new file mode 100644 index 000000000..04aabacad --- /dev/null +++ b/predeployed/test/genesis.json @@ -0,0 +1,353 @@ +{ + "alloc": { + "0xD2AAa001D2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102745760003560e01c80636a156b9a11610151578063bbc4e8c2116100c3578063e6ab840311610087578063e6ab8403146105a3578063f2f6360514610604578063f399e22e14610617578063f68016b71461062a578063f79f795414610633578063f8c88a161461064657600080fd5b8063bbc4e8c21461053b578063bdb40cb014610562578063ca15c8731461056a578063cab010c91461057d578063d547741f1461059057600080fd5b80639010d07c116101155780639010d07c146104d457806391d14854146104e757806394489202146104fa578063999ab9aa1461050d578063a217fddf14610520578063a8bb1b7d1461052857600080fd5b80636a156b9a146104635780636e2f37b01461048857806377fe0f311461049b578063788bc78c146104ae5780637aa38a7c146104c157600080fd5b80633b690b6b116101ea57806352dc24ee116101ae57806352dc24ee146103f357806353498cdd1461040657806354fd4d5014610415578063603e5d131461042a578063654d88281461043d57806367ec60201461045057600080fd5b80633b690b6b1461039c5780633bf2f737146103a55780633cdd2cc3146103b85780634d203859146103cb578063523c8ab6146103de57600080fd5b8063214883401161023c57806321488340146102ec578063248a9ca31461030c57806328c5e1821461032f5780632f2ff15d1461036157806336568abe146103765780633b597ffe1461038957600080fd5b806301ffc9a7146102795780630fc307a8146102a157806313c52260146102c2578063198e687c146102d75780631cf5379d146102df575b600080fd5b61028c6102873660046133eb565b610659565b60405190151581526020015b60405180910390f35b6102b46102af366004613415565b610684565b604051908152602001610298565b6102b46000805160206141d883398151915281565b6102b4604081565b60d35461028c9060ff1681565b6102ff6102fa36600461342e565b61069b565b604051610298919061345a565b6102b461031a366004613415565b60009081526065602052604090206001015490565b6102b46040516613585a5b9b995d60ca1b60208201526027016040516020818303038152906040528051906020012081565b61037461036f3660046134bc565b6107da565b005b6103746103843660046134bc565b610804565b610374610397366004613415565b610882565b6102b460cd5481565b6102b46103b33660046135e5565b610948565b6103746103c63660046135e5565b6109be565b6103746103d9366004613619565b610aa7565b6102b460008051602061419883398151915281565b61028c610401366004613648565b610be1565b6102b4670de0b6b3a764000081565b61041d610bf4565b60405161029891906136c5565b610374610438366004613720565b610c82565b61028c61044b3660046134bc565b610f25565b6102b461045e3660046137da565b610f3d565b61047062695d1f60891b81565b6040516001600160a01b039091168152602001610298565b610374610496366004613415565b610fb6565b6102b46104a93660046137da565b6110ea565b6103746104bc3660046137da565b611190565b61028c6104cf36600461381b565b611230565b6104706104e23660046138c5565b611269565b61028c6104f53660046134bc565b611281565b6103746105083660046138e7565b6112ac565b61028c61051b3660046135e5565b611362565b6102b4600081565b610374610536366004613619565b6113ab565b6102b47f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c81565b6102b4600a81565b6102b4610578366004613415565b6114a5565b61037461058b36600461393f565b6114bc565b61037461059e3660046134bc565b611546565b6105de6105b1366004613415565b60c96020526000908152604090208054600182015460028301546003909301549192909160ff9091169084565b604080519485526020850193909352901515918301919091526060820152608001610298565b6103746106123660046137da565b61156b565b610374610625366004613985565b6115f2565b6102b460cb5481565b60cc54610470906001600160a01b031681565b61037461065436600461393f565b6117a3565b60006001600160e01b03198216635a05180f60e01b148061067e575061067e8261182d565b92915050565b600081815260d16020526040812061067e90611862565b606081831080156106b65750600a6106b384846139ea565b11155b80156106d85750600084815260d1602052604090206106d490611862565b8211155b61071e5760405162461bcd60e51b815260206004820152601260248201527114985b99d9481a5cc81a5b98dbdc9c9958dd60721b60448201526064015b60405180910390fd5b61072883836139ea565b6001600160401b0381111561073f5761073f6134ec565b604051908082528060200260200182016040528015610768578160200160208202803683370190505b509050825b828110156107d257600085815260d16020526040902061078d908261186c565b8261079886846139ea565b815181106107a8576107a86139fd565b6001600160a01b0390921660209283029190910190910152806107ca81613a13565b91505061076d565b509392505050565b6000828152606560205260409020600101546107f581611878565b6107ff8383611885565b505050565b6001600160a01b03811633146108745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610715565b61087e82826118a7565b5050565b6108ac7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33611281565b6109075760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2073657420636f6044820152651b9cdd185b9d60d21b6064820152608401610715565b60cb5460408051918252602082018390527f8abddb75fd50f7583079c0b550ec7a54fa3fd8d5dd1d2dfdc473f7ce27e3b9ac910160405180910390a160cb55565b6000808260405160200161095c9190613a2c565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff166109a65760405162461bcd60e51b815260040161071590613a48565b600090815260c9602052604090206003015492915050565b6109d66000805160206141d883398151915233611281565b6109f25760405162461bcd60e51b815260040161071590613a8c565b600081604051602001610a059190613a2c565b604051602081830303815290604052805190602001209050604051602001610a3a906613585a5b9b995d60ca1b815260070190565b604051602081830303815290604052805190602001208103610a9e5760405162461bcd60e51b815260206004820152601960248201527f4d61696e6e65742063616e6e6f742062652072656d6f766564000000000000006044820152606401610715565b61087e826118c9565b610abf60008051602061419883398151915233611281565b610adb5760405162461bcd60e51b815260040161071590613ac1565b6001600160a01b0381163b610b325760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401610715565b610b4e8160d15b600080805260209190915260409020906119b0565b15610b6b5760405162461bcd60e51b815260040161071590613b0a565b6000805260d1602052610b9d7efa5413e7b01fc543d01f0911de573ace463b956369df4472f39030e8d98b77826119d2565b506040516001600160a01b03821681526000907f03bcd152926369e3cf05cb7af471a15d680e8ec5d20b13705048d14e94679365906020015b60405180910390a250565b6000610bed83836119e7565b9392505050565b60d28054610c0190613b4e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2d90613b4e565b8015610c7a5780601f10610c4f57610100808354040283529160200191610c7a565b820191906000526020600020905b815481529060010190602001808311610c5d57829003601f168201915b505050505081565b60d35460ff1615610cce5760405162461bcd60e51b81526020600482015260166024820152754d65737361676520697320696e2070726f677265737360501b6044820152606401610715565b60d3805460ff19166001179055604051600090610cf19088908890602001613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff16610d665760405162461bcd60e51b815260206004820152601860248201527710da185a5b881a5cc81b9bdd081a5b9a5d1a585b1a5e995960421b6044820152606401610715565b600a831115610dab5760405162461bcd60e51b8152602060048201526011602482015270546f6f206d616e79206d6573736167657360781b6044820152606401610715565b610dc1610dbb8585888b8b611a85565b836119e7565b610e0d5760405162461bcd60e51b815260206004820152601960248201527f5369676e6174757265206973206e6f74207665726966696564000000000000006044820152606401610715565b600081815260c960205260409020548514610e905760405162461bcd60e51b815260206004820152603860248201527f5374617274696e6720636f756e746572206973206e6f74207175616c20746f2060448201527f696e636f6d696e67206d65737361676520636f756e74657200000000000000006064820152608401610715565b600081815260c9602052604081208054859290610eae908490613b92565b90915550600090505b83811015610f0957610ef782868684818110610ed557610ed56139fd565b9050602002810190610ee79190613ba5565b610ef2896001613b92565b611c00565b80610f0181613a13565b915050610eb7565b50610f12611e23565b505060d3805460ff191690555050505050565b600082815260d160205260408120610bed90836119b0565b6000808383604051602001610f53929190613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff16610f9d5760405162461bcd60e51b815260040161071590613a48565b600090815260c960205260409020600101549392505050565b600054610100900460ff1615808015610fd65750600054600160ff909116105b80610ff05750303b158015610ff0575060005460ff166001145b61100c5760405162461bcd60e51b815260040161071590613bbb565b6000805460ff19166001179055801561102f576000805461ff0019166101001790555b611037611ff9565b611042600033612066565b61105a6000805160206141d883398151915233612066565b61107260008051602061419883398151915233612066565b61109c7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33612066565b60cb829055801561087e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6000808383604051602001611100929190613b82565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff1661117a5760405162461bcd60e51b815260206004820152601f60248201527f536f7572636520636861696e206973206e6f7420696e697469616c697a6564006044820152606401610715565b600090815260c960205260409020549392505050565b61119b600033611281565b6111e75760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401610715565b7f22efc5f993dce37856b77dd72d7d7661032380c9728c4133f3c071c591bc6ca760d2838360405161121b93929190613c32565b60405180910390a160d26107ff828483613d17565b8051600090815260ce6020908152604080832082850151845290915281205461125883612070565b810361126357600191505b50919050565b6000828152609760205260408120610bed908361186c565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6112b78383836120e6565b60006040518060a00160405280858152602001600160c96000888152602001908152602001600020600101546112ed91906139ea565b81523360208201526001600160a01b0385166040820152606001839052805190915061131882612070565b600082815260ce6020908152604080832060d08084528285208054865291845291842094909455848352905281546001929190611356908490613b92565b90915550505050505050565b600060c96000836040516020016113799190613a2c565b60408051601f198184030181529181528151602092830120835290820192909252016000206002015460ff1692915050565b6113c360008051602061419883398151915233611281565b6113df5760405162461bcd60e51b815260040161071590613ac1565b6113ea8160d1610b39565b6114365760405162461bcd60e51b815260206004820181905260248201527f457874726120636f6e7472616374206973206e6f7420726567697374657265646044820152606401610715565b6000805260d16020526114687efa5413e7b01fc543d01f0911de573ace463b956369df4472f39030e8d98b77826121f9565b506040516001600160a01b03821681526000907f4d393b64277bfc0b02e0459a74c316c7f22069352a678319fd8139ba4085e06190602001610bd6565b600081815260976020526040812061067e90611862565b6114d460008051602061419883398151915233611281565b6114f05760405162461bcd60e51b815260040161071590613ac1565b6000826040516020016115039190613a2c565b60405160208183030381529060405280519060200120905060cd54810361153c5760405162461bcd60e51b815260040161071590613dd7565b6107ff818361220e565b60008281526065602052604090206001015461156181611878565b6107ff83836118a7565b60008282604051602001611580929190613b82565b60405160208183030381529060405280519060200120905060cd5481036115e95760405162461bcd60e51b815260206004820152601c60248201527f53636861696e2063616e6e6f7420636f6e6e65637420697473656c66000000006044820152606401610715565b6107ff8161236e565b600054610100900460ff16158080156116125750600054600160ff909116105b8061162c5750303b15801561162c575060005460ff166001145b6116485760405162461bcd60e51b815260040161071590613bbb565b6000805460ff19166001179055801561166b576000805461ff0019166101001790555b611677622dc6c0610fb6565b60cc80546001600160a01b0385166001600160a01b03199091161790556040805160808101825260008082526020808301829052600183850152606083018290529251919260c9926116d791016613585a5b9b995d60ca1b815260070190565b60408051808303601f190181529181528151602092830120835282820193909352908201600020835181558382015160018201558383015160028201805460ff19169115159190911790556060909301516003909301929092555161173e91849101613a2c565b60408051601f19818403018152919052805160209091012060cd5580156107ff576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6117bb60008051602061419883398151915233611281565b6117d75760405162461bcd60e51b815260040161071590613ac1565b6000826040516020016117ea9190613a2c565b60405160208183030381529060405280519060200120905060cd5481036118235760405162461bcd60e51b815260040161071590613dd7565b6107ff8183612462565b60006001600160e01b03198216637965db0b60e01b148061067e57506301ffc9a760e01b6001600160e01b031983161461067e565b600061067e825490565b6000610bed838361250d565b6118828133612537565b50565b61188f828261259b565b60008281526097602052604090206107ff90826119d2565b6118b18282612621565b60008281526097602052604090206107ff90826121f9565b6118e16000805160206141d883398151915233611281565b6118fd5760405162461bcd60e51b815260040161071590613a8c565b6000816040516020016119109190613a2c565b60408051601f198184030181529181528151602092830120600081815260c990935291206002015490915060ff166119855760405162461bcd60e51b815260206004820152601860248201527710da185a5b881a5cc81b9bdd081a5b9a5d1a585b1a5e995960421b6044820152606401610715565b600090815260c9602052604081208181556001810182905560028101805460ff191690556003015550565b6001600160a01b03811660009081526001830160205260408120541515610bed565b6000610bed836001600160a01b038416612688565b604080518082018252823581526020808401359082015260cc548251632aa77bd360e11b81528351600094610bed949388936080808a013594938a01359360608b0135936001600160a01b03169263554ef7a69260048083019391928290030181865afa158015611a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a809190613e5d565b6126d7565b6000808383604051602001611a9b929190613b82565b60408051808303601f190181528282528051602091820120908301819052908201879052915060009060600160405160208183030381529060405280519060200120905060005b87811015611bf45781898983818110611afd57611afd6139fd565b9050602002810190611b0f9190613ba5565b611b1d906020810190613619565b8a8a84818110611b2f57611b2f6139fd565b9050602002810190611b419190613ba5565b611b52906040810190602001613619565b6040805160208101949094526001600160a01b0392831690840152166060820152608001604051602081830303815290604052898983818110611b9757611b976139fd565b9050602002810190611ba99190613ba5565b611bb7906040810190613ea0565b604051602001611bc993929190613ee6565b6040516020818303038152906040528051906020012091508080611bec90613a13565b915050611ae2565b50979650505050505050565b611c22611c136040840160208501613619565b6001600160a01b03163b151590565b611c9057806000805160206141f8833981519152604051611c839060208082526026908201527f44657374696e6174696f6e20636f6e7472616374206973206e6f74206120636f6040820152651b9d1c9858dd60d21b606082015260800190565b60405180910390a2505050565b611ca06040830160208401613619565b6001600160a01b031663884cee5a60cb5485856000016020810190611cc59190613619565b611cd26040880188613ea0565b6040518663ffffffff1660e01b8152600401611cf19493929190613f0e565b600060405180830381600088803b158015611d0b57600080fd5b5087f193505050508015611d1d575060015b6107ff57611d29613f39565b806308c379a003611d7e5750611d3d613f55565b80611d485750611dd8565b816000805160206141f8833981519152611d638360406128a1565b604051611d7091906136c5565b60405180910390a250505050565b634e487b7103611dd857611d90613fde565b90611d9b5750611dd8565b816000805160206141f883398151915282604051602001611dbe91815260200190565b60408051601f1981840301815290829052611d70916136c5565b3d808015611e02576040519150601f19603f3d011682016040523d82523d6000602084013e611e07565b606091505b50816000805160206141f8833981519152611d638360406128a1565b60003a5a611e319190613ffe565b611e3c903331613b92565b905062695d1f60891b803b15801590611f275750806001600160a01b03166391d14854826001600160a01b031663bc2a1e8d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec1919061401d565b6040516001600160e01b031960e084901b1681526004810191909152306024820152604401602060405180830381865afa158015611f03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f279190614036565b8015611f3a5750670de0b6b3a764000082105b1561087e576000611f5383670de0b6b3a76400006139ea565b9050816001600160a01b031631811015611fcd5760405163204a3e9360e01b8152336004820152602481018290526001600160a01b0383169063204a3e93906044015b600060405180830381600087803b158015611fb057600080fd5b505af1158015611fc4573d6000803e3d6000fd5b50505050505050565b604051630a79309b60e01b81523360048201526001600160a01b03831690630a79309b90602401611f96565b600054610100900460ff166120645760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610715565b565b61087e8282611885565b6000808260000151836020015160001b846040015160601b6bffffffffffffffffffffffff1916856060015160601b6bffffffffffffffffffffffff191686608001516040516020016120c7959493929190614058565b60408051601f1981840301815291905280516020909101209392505050565b600083815260c9602052604090206002015460ff166121175760405162461bcd60e51b815260040161071590613a48565b6121208361296b565b600083815260c96020526040908190206001015490513390829086907f803d7f3ca0e5f93fcce39fa29812ed57a95a151594966e17125220132741c6b09061216b9088908890614093565b60405180910390a4600084815260c96020908152604091829020600301548251848152918201527f64ab4eb9f2b913fd01467c69e91e32483420fab6be93c3a7559adbe1b0356845910160405180910390a1600084815260c9602052604081206001018054916121da83613a13565b9091555050506000928352505060c96020526040902043600390910155565b6000610bed836001600160a01b0384166129dc565b6001600160a01b0381163b6122655760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401610715565b6122818160d15b600085815260209190915260409020906119b0565b1561229e5760405162461bcd60e51b815260040161071590613b0a565b6122a98160d1610b39565b156123125760405162461bcd60e51b815260206004820152603360248201527f457874726120636f6e747261637420697320616c7265616479207265676973746044820152726572656420666f7220616c6c20636861696e7360681b6064820152608401610715565b600082815260d16020526040902061232a90826119d2565b506040516001600160a01b038216815282907f03bcd152926369e3cf05cb7af471a15d680e8ec5d20b13705048d14e94679365906020015b60405180910390a25050565b6123866000805160206141d883398151915233611281565b6123a25760405162461bcd60e51b815260040161071590613a8c565b600081815260c9602052604090206002015460ff16156124045760405162461bcd60e51b815260206004820152601a60248201527f436861696e20697320616c726561647920636f6e6e65637465640000000000006044820152606401610715565b604080516080810182526000808252602080830182815260018486018181526060860185815297855260c99093529490922092518355905192820192909255905160028201805460ff19169115159190911790559051600390910155565b61246d8160d161226c565b6124b95760405162461bcd60e51b815260206004820181905260248201527f457874726120636f6e7472616374206973206e6f7420726567697374657265646044820152606401610715565b600082815260d1602052604090206124d190826121f9565b506040516001600160a01b038216815282907f4d393b64277bfc0b02e0459a74c316c7f22069352a678319fd8139ba4085e06190602001612362565b6000826000018281548110612524576125246139fd565b9060005260206000200154905092915050565b6125418282611281565b61087e57612559816001600160a01b03166014612ad6565b612564836020612ad6565b6040516020016125759291906140b7565b60408051601f198184030181529082905262461bcd60e51b8252610715916004016136c5565b6125a58282611281565b61087e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556125dd3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61262b8282611281565b1561087e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120546126cf5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561067e565b50600061067e565b60006126e287612c71565b6127275760405162461bcd60e51b815260206004820152601660248201527514da59db985d1d5c99481a5cc81b9bdd081d985b1a5960521b6044820152606401610715565b61273386868686612ca7565b61273f57506000612897565b600061274e8860200151612d95565b905061275e886000015182612dba565b61279b5760405162461bcd60e51b815260206004820152600e60248201526d5369676e206e6f7420696e20473160901b6044820152606401610715565b6127a58585612dba565b6127e25760405162461bcd60e51b815260206004820152600e60248201526d48617368206e6f7420696e20473160901b6044820152606401610715565b60006127ec612df0565b90506127f784612eb0565b61283a5760405162461bcd60e51b8152602060048201526014602482015273283ab13634b19025b2bc903737ba1034b710239960611b6044820152606401610715565b6128928960000151838360000151602001518460000151600001518560200151602001518660200151600001518c8c8c60000151602001518d60000151600001518e60200151602001518f6020015160000151612ec4565b925050505b9695505050505050565b60606000835183106128b45783516128b6565b825b90506000816001600160401b038111156128d2576128d26134ec565b6040519080825280601f01601f1916602001820160405280156128fc576020820181803683370190505b50905060005b828110156129625785818151811061291c5761291c6139fd565b602001015160f81c60f81b828281518110612939576129396139fd565b60200101906001600160f81b031916908160001a9053508061295a81613a13565b915050612902565b50949350505050565b612976600033610f25565b8061298657506129868133610f25565b6118825760405162461bcd60e51b815260206004820152602160248201527f53656e64657220636f6e7472616374206973206e6f74207265676973746572656044820152601960fa1b6064820152608401610715565b60008181526001830160205260408120548015612ac5576000612a006001836139ea565b8554909150600090612a14906001906139ea565b9050818114612a79576000866000018281548110612a3457612a346139fd565b9060005260206000200154905080876000018481548110612a5757612a576139fd565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612a8a57612a8a61412c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061067e565b600091505061067e565b5092915050565b60606000612ae5836002613ffe565b612af0906002613b92565b6001600160401b03811115612b0757612b076134ec565b6040519080825280601f01601f191660200182016040528015612b31576020820181803683370190505b509050600360fc1b81600081518110612b4c57612b4c6139fd565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612b7b57612b7b6139fd565b60200101906001600160f81b031916908160001a9053506000612b9f846002613ffe565b612baa906001613b92565b90505b6001811115612c22576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612bde57612bde6139fd565b1a60f81b828281518110612bf457612bf46139fd565b60200101906001600160f81b031916908160001a90535060049490941c93612c1b81614142565b9050612bad565b508315610bed5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610715565b60006000805160206141b8833981519152826000015110801561067e575050602001516000805160206141b88339815191521190565b60006064841115612cba57506000612d8d565b6000612cd46000805160206141b88339815191528761416f565b90506000805160206141b8833981519152612cef8683613b92565b612cf9919061416f565b905060006000805160206141b883398151915260036000805160206141b8833981519152846000805160206141b883398151915286870909089050612d4d60026000805160206141b8833981519152614183565b841080612d6b5750806000805160206141b883398151915285860914155b80612d765750848214155b15612d8657600092505050612d8d565b6001925050505b949350505050565b60006000805160206141b8833981519152612db083826139ea565b61067e919061416f565b60006000805160206141b883398151915280600381868188890909088180612de457612de4614159565b84850914949350505050565b612df861336a565b50604080516080810182527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed8183019081527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26060830152815281518083019092527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa82527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60208381019190915281019190915290565b600061067e82600001518360200151612f94565b600080612ecf6133ae565b8e8152602081018e9052604081018d9052606081018c9052608081018b905260a081018a905260c0810189905260e081018890526101008101879052610120810186905261014081018590526101608101849052612f2b6133cd565b602081610180846008600019fa925082612f7e5760405162461bcd60e51b815260206004820152601460248201527314185a5c9a5b99c818da1958dac819985a5b195960621b6044820152606401610715565b5115159f9e505050505050505050505050505050565b6000612fa08383613068565b15612fad5750600161067e565b6000612fb88361309b565b9050600061304b613028604080518082018252600080825260209182015281518083019092527f2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e582527e9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d29082015290565b61304561303e886130388a61309b565b90613151565b8590613264565b90613264565b805190915015801561305f57506020810151155b95945050505050565b815160009015801561307c57506020830151155b8015613089575081516001145b8015610bed5750506020015115919050565b60408051808201909152600080825260208201526000805160206141b883398151915260008160208501518551099050600082806130db576130db614159565b83806130e9576130e9614159565b84806130f7576130f7614159565b60208801516131076001886139ea565b09875108848061311957613119614159565b60208801518851080990506040518060400160405280828152602001848061314357613143614159565b848508905295945050505050565b604080518082019091526000808252602082015260006000805160206141b8833981519152905060006040518060400160405280838061319357613193614159565b8651885109815260200183806131ab576131ab614159565b86602001518860200151099052905081806131c8576131c8614159565b82806131d6576131d6614159565b60208301516131e66001866139ea565b09825108835281806131fa576131fa614159565b828061320857613208614159565b602083015183510861321a90846139ea565b838061322857613228614159565b848061323657613236614159565b6020880151885108858061324c5761324c614159565b60208a01518a51080908602084015250909392505050565b6040805180820190915260008082526020820152815183516000805160206141b883398151915291116132b557808061329f5761329f614159565b83516132ab90836139ea565b85510882526132ea565b8081806132c4576132c4614159565b85516132d090846139ea565b8551086132dd90836139ea565b6132e7919061416f565b82525b826020015184602001511061332657808061330757613307614159565b602084015161331690836139ea565b8560200151086020830152612acf565b80818061333557613335614159565b602086015161334490846139ea565b85602001510861335490836139ea565b61335e919061416f565b60208301525092915050565b604080516080810182526000918101828152606082019290925290819081526020016133a9604051806040016040528060008152602001600081525090565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b6000602082840312156133fd57600080fd5b81356001600160e01b031981168114610bed57600080fd5b60006020828403121561342757600080fd5b5035919050565b60008060006060848603121561344357600080fd5b505081359360208301359350604090920135919050565b6020808252825182820181905260009190848201906040850190845b8181101561349b5783516001600160a01b031683529284019291840191600101613476565b50909695505050505050565b6001600160a01b038116811461188257600080fd5b600080604083850312156134cf57600080fd5b8235915060208301356134e1816134a7565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60a081018181106001600160401b0382111715613521576135216134ec565b60405250565b604081018181106001600160401b0382111715613521576135216134ec565b601f8201601f191681016001600160401b038111828210171561356b5761356b6134ec565b6040525050565b600082601f83011261358357600080fd5b81356001600160401b0381111561359c5761359c6134ec565b6040516135b3601f8301601f191660200182613546565b8181528460208386010111156135c857600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156135f757600080fd5b81356001600160401b0381111561360d57600080fd5b612d8d84828501613572565b60006020828403121561362b57600080fd5b8135610bed816134a7565b600060a0828403121561126357600080fd5b60008060c0838503121561365b57600080fd5b8235915061366c8460208501613636565b90509250929050565b60005b83811015613690578181015183820152602001613678565b50506000910152565b600081518084526136b1816020860160208601613675565b601f01601f19169290920160200192915050565b602081526000610bed6020830184613699565b60008083601f8401126136ea57600080fd5b5081356001600160401b0381111561370157600080fd5b60208301915083602082850101111561371957600080fd5b9250929050565b600080600080600080610100878903121561373a57600080fd5b86356001600160401b038082111561375157600080fd5b61375d8a838b016136d8565b909850965060208901359550604089013591508082111561377d57600080fd5b818901915089601f83011261379157600080fd5b8135818111156137a057600080fd5b8a60208260051b85010111156137b557600080fd5b6020830195508094505050506137ce8860608901613636565b90509295509295509295565b600080602083850312156137ed57600080fd5b82356001600160401b0381111561380357600080fd5b61380f858286016136d8565b90969095509350505050565b60006020828403121561382d57600080fd5b81356001600160401b038082111561384457600080fd5b9083019060a0828603121561385857600080fd5b60405161386481613502565b82358152602083013560208201526040830135613880816134a7565b60408201526060830135613893816134a7565b60608201526080830135828111156138aa57600080fd5b6138b687828601613572565b60808301525095945050505050565b600080604083850312156138d857600080fd5b50508035926020909101359150565b6000806000606084860312156138fc57600080fd5b83359250602084013561390e816134a7565b915060408401356001600160401b0381111561392957600080fd5b61393586828701613572565b9150509250925092565b6000806040838503121561395257600080fd5b82356001600160401b0381111561396857600080fd5b61397485828601613572565b92505060208301356134e1816134a7565b6000806040838503121561399857600080fd5b82356139a3816134a7565b915060208301356001600160401b038111156139be57600080fd5b6139ca85828601613572565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561067e5761067e6139d4565b634e487b7160e01b600052603260045260246000fd5b600060018201613a2557613a256139d4565b5060010190565b60008251613a3e818460208701613675565b9190910192915050565b60208082526024908201527f44657374696e6174696f6e20636861696e206973206e6f7420696e697469616c6040820152631a5e995960e21b606082015260800190565b6020808252818101527f434841494e5f434f4e4e4543544f525f524f4c45206973207265717569726564604082015260600190565b60208082526029908201527f45585452415f434f4e54524143545f5245474953545241525f524f4c45206973604082015268081c995c5d5a5c995960ba1b606082015260800190565b60208082526024908201527f457874726120636f6e747261637420697320616c726561647920726567697374604082015263195c995960e21b606082015260800190565b600181811c90821680613b6257607f821691505b60208210810361126357634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b8082018082111561067e5761067e6139d4565b60008235605e19833603018112613a3e57600080fd5b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b604081526000808554613c4481613b4e565b8060408601526060600180841660008114613c665760018114613c8057613cb1565b60ff1985168884015283151560051b880183019550613cb1565b8a60005260208060002060005b86811015613ca85781548b8201870152908401908201613c8d565b8a018501975050505b50505050508281036020840152612897818587613c09565b601f8211156107ff57600081815260208120601f850160051c81016020861015613cf05750805b601f850160051c820191505b81811015613d0f57828155600101613cfc565b505050505050565b6001600160401b03831115613d2e57613d2e6134ec565b613d4283613d3c8354613b4e565b83613cc9565b6000601f841160018114613d765760008515613d5e5750838201355b600019600387901b1c1916600186901b178355613dd0565b600083815260209020601f19861690835b82811015613da75786850135825560209485019460019092019101613d87565b5086821015613dc45760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208082526030908201527f44657374696e6174696f6e20636861696e20686173682063616e6e6f7420626560408201526f1032b8bab0b6103a379034ba39b2b63360811b606082015260800190565b600060408284031215613e3957600080fd5b604051613e4581613527565b80915082518152602083015160208201525092915050565b600060808284031215613e6f57600080fd5b604051613e7b81613527565b613e858484613e27565b8152613e948460408501613e27565b60208201529392505050565b6000808335601e19843603018112613eb757600080fd5b8301803591506001600160401b03821115613ed157600080fd5b60200191503681900382131561371957600080fd5b60008451613ef8818460208901613675565b8201838582376000930192835250909392505050565b8481526001600160a01b03841660208201526060604082018190526000906128979083018486613c09565b600060033d1115613f525760046000803e5060005160e01c5b90565b600060443d1015613f635790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715613f9257505050505090565b8285019150815181811115613faa5750505050505090565b843d8701016020828501011115613fc45750505050505090565b613fd360208286010187613546565b509095945050505050565b60008060233d1115613ffa576020600460003e50506000516001905b9091565b6000816000190483118215151615614018576140186139d4565b500290565b60006020828403121561402f57600080fd5b5051919050565b60006020828403121561404857600080fd5b81518015158114610bed57600080fd5b85815284602082015283604082015282606082015260008251614082816080850160208701613675565b919091016080019695505050505050565b6001600160a01b0383168152604060208201819052600090612d8d90830184613699565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516140ef816017850160208801613675565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614120816028840160208801613675565b01602801949350505050565b634e487b7160e01b600052603160045260246000fd5b600081614151576141516139d4565b506000190190565b634e487b7160e01b600052601260045260246000fd5b60008261417e5761417e614159565b500690565b60008261419257614192614159565b50049056fe6155b5aac15ce9aa193c0527a6f43be0a36a7e2e7496c2b615c0e5f92284277330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd472785f35fe7d8743aa971942d8474737bb31895d396eff2cc688a481e0221e1914b7d3908626050c0d998d657e4e6f31cb43ed736bf2b9a1a0192494537ca0e59a26469706673582212202d276ec52211cb6b0422d5ff12645bf923438087729432e09c60f0ddc94bf80e64736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xD2AAa002d2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80639010d07c1161008c578063ab2a585311610066578063ab2a5853146101db578063ca15c873146101e3578063d547741f146101f6578063ecfc7efe1461020957600080fd5b80639010d07c1461019557806391d14854146101c0578063a217fddf146101d357600080fd5b806336568abe116100c857806336568abe1461015d578063554ef7a614610170578063573c8aba146101855780638129fc1c1461018d57600080fd5b806301ffc9a7146100ef578063248a9ca3146101175780632f2ff15d14610148575b600080fd5b6101026100fd366004610b3e565b610211565b60405190151581526020015b60405180910390f35b61013a610125366004610b68565b60009081526065602052604090206001015490565b60405190815260200161010e565b61015b610156366004610b81565b61023c565b005b61015b61016b366004610b81565b610266565b6101786102e9565b60405161010e9190610bbd565b61013a604081565b61015b6102fe565b6101a86101a3366004610bec565b61041a565b6040516001600160a01b03909116815260200161010e565b6101026101ce366004610b81565b610439565b61013a600081565b61013a601381565b61013a6101f1366004610b68565b610464565b61015b610204366004610b81565b61047b565b61013a601981565b60006001600160e01b03198216635a05180f60e01b14806102365750610236826104a0565b92915050565b600082815260656020526040902060010154610257816104d5565b61026183836104df565b505050565b6001600160a01b03811633146102db5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6102e58282610501565b5050565b6102f1610afa565b6102f9610523565b905090565b600054610100900460ff161580801561031e5750600054600160ff909116105b806103385750303b158015610338575060005460ff166001145b61039b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102d2565b6000805460ff1916600117905580156103be576000805461ff0019166101001790555b6103c66105e3565b6103d1600033610650565b8015610417576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6000828152609760205260408120610432908361065a565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b600081815260976020526040812061023690610666565b600082815260656020526040902060010154610496816104d5565b6102618383610501565b60006001600160e01b03198216637965db0b60e01b148061023657506301ffc9a760e01b6001600160e01b0319831614610236565b6104178133610670565b6104e982826106d4565b6000828152609760205260409020610261908261075a565b61050b828261076f565b600082815260976020526040902061026190826107d6565b61052b610afa565b600060409050600080600080600085516080816000836019600019fa815160208084015160408501516060909501518c518490528c5183018290528c83018051879052519092018290529298509096509094509092509050846105da5760405162461bcd60e51b815260206004820152602160248201527f4765742063757272656e7420424c53207075626c6963206b6579206661696c656044820152601960fa1b60648201526084016102d2565b50505050505090565b600054610100900460ff1661064e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016102d2565b565b6102e582826104df565b600061043283836107eb565b6000610236825490565b61067a8282610439565b6102e557610692816001600160a01b03166014610815565b61069d836020610815565b6040516020016106ae929190610c32565b60408051601f198184030181529082905262461bcd60e51b82526102d291600401610ca7565b6106de8282610439565b6102e55760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107163390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610432836001600160a01b0384166109b1565b6107798282610439565b156102e55760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610432836001600160a01b038416610a00565b600082600001828154811061080257610802610cda565b9060005260206000200154905092915050565b60606000610824836002610d06565b61082f906002610d25565b67ffffffffffffffff81111561084757610847610d38565b6040519080825280601f01601f191660200182016040528015610871576020820181803683370190505b509050600360fc1b8160008151811061088c5761088c610cda565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106108bb576108bb610cda565b60200101906001600160f81b031916908160001a90535060006108df846002610d06565b6108ea906001610d25565b90505b6001811115610962576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061091e5761091e610cda565b1a60f81b82828151811061093457610934610cda565b60200101906001600160f81b031916908160001a90535060049490941c9361095b81610d4e565b90506108ed565b5083156104325760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016102d2565b60008181526001830160205260408120546109f857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610236565b506000610236565b60008181526001830160205260408120548015610ae9576000610a24600183610d65565b8554909150600090610a3890600190610d65565b9050818114610a9d576000866000018281548110610a5857610a58610cda565b9060005260206000200154905080876000018481548110610a7b57610a7b610cda565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610aae57610aae610d78565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610236565b6000915050610236565b5092915050565b60408051608081018252600091810182815260608201929092529081908152602001610b39604051806040016040528060008152602001600081525090565b905290565b600060208284031215610b5057600080fd5b81356001600160e01b03198116811461043257600080fd5b600060208284031215610b7a57600080fd5b5035919050565b60008060408385031215610b9457600080fd5b8235915060208301356001600160a01b0381168114610bb257600080fd5b809150509250929050565b815180518252602090810151908201526080810160208381015180516040850152908101516060840152610af3565b60008060408385031215610bff57600080fd5b50508035926020909101359150565b60005b83811015610c29578181015183820152602001610c11565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351610c6a816017850160208801610c0e565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351610c9b816028840160208801610c0e565b01602801949350505050565b6020815260008251806020840152610cc6816040850160208701610c0e565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615610d2057610d20610cf0565b500290565b8082018082111561023657610236610cf0565b634e487b7160e01b600052604160045260246000fd5b600081610d5d57610d5d610cf0565b506000190190565b8181038181111561023657610236610cf0565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209eb591a65bac8d1c788efa82781806a242f292ebf8c3827b20d69ee3868daec864736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xD2AaA009d2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040523480156200001157600080fd5b5060043610620002795760003560e01c80636d6c68e61162000155578063c5d7666411620000c7578063dec2deb61162000086578063dec2deb6146200064e578063e3e50fa41462000663578063edcc12b5146200068f578063f23a6e6114620006a6578063f5b52e1f14620006bd57600080fd5b8063c5d7666414620005ca578063ca15c87314620005e1578063cb703bff14620005f8578063cc5b715b146200060f578063d547741f146200063757600080fd5b8063a217fddf1162000114578063a217fddf1462000549578063aebaaca91462000552578063b9581c501462000578578063bc197c811462000582578063c0e312dc14620005b357600080fd5b80636d6c68e614620004d95780638369091714620004ed578063884cee5a14620005045780639010d07c146200051b57806391d14854146200053257600080fd5b80632f2ff15d11620001ef57806350f4428011620001ae57806350f44280146200044d5780635573b8b6146200048357806357157cd914620004975780636ce681d214620004ae5780636d61128614620004c557600080fd5b80632f2ff15d14620003e757806336568abe14620003fe57806339927cf914620004155780633b690b6b146200042c5780633fa194ce146200043657600080fd5b806315ecfe5e116200023c57806315ecfe5e1462000355578063248a9ca3146200038c57806328c5e18214620003b25780632d32926214620003bc5780632dc151de14620003d357600080fd5b806301ffc9a7146200027e578063029996b814620002aa5780630b885ac314620002b65780630f1a8f7414620002cd5780631420de3f1462000312575b600080fd5b620002956200028f36600462003fd6565b620006d4565b60405190151581526020015b60405180910390f35b620002b462000702565b005b620002b4620002c73660046200415c565b6200075a565b620002f9620002de366004620041f1565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001620002a1565b62000346620003233660046200420b565b60d260209081526000938452604080852082529284528284209052825290205481565b604051908152602001620002a1565b620002f96200036636600462004246565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b620003466200039d366004620041f1565b60009081526065602052604090206001015490565b6200034662000839565b620002b4620003cd366004620042c4565b62000884565b60ca54620002f9906001600160a01b031681565b620002b4620003f836600462004246565b62000aa0565b620002b46200040f36600462004246565b62000ace565b620002956200042636600462004330565b62000b50565b6200034660cc5481565b620003466000805160206200833c83398151915281565b620004746040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002a19190620043c9565b60c954620002f9906001600160a01b031681565b620002b4620004a836600462004425565b62000bad565b620002b4620004bf3660046200415c565b62000dcd565b60cd54620002f9906001600160a01b031681565b60cb54620002f9906001600160a01b031681565b620002b4620004fe366004620044df565b62000ff0565b620002b4620005153660046200456a565b6200110e565b620002f96200052c366004620045cb565b620012d0565b620002956200054336600462004246565b620012f1565b62000346600081565b6200029562000563366004620045ee565b60d06020526000908152604090205460ff1681565b620002b46200131c565b62000599620005933660046200460e565b62001365565b6040516001600160e01b03199091168152602001620002a1565b620002b4620005c436600462004330565b620013ef565b620002b4620005db366004620046da565b6200150d565b62000346620005f2366004620041f1565b62001826565b620002b46200060936600462004749565b6200183f565b620003467ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b620002b46200064836600462004246565b62001997565b60cd546200029590600160a01b900460ff1681565b620002f962000674366004620045ee565b60cf602052600090815260409020546001600160a01b031681565b620002b4620006a0366004620045ee565b620019c0565b62000599620006b7366004620047a5565b62001adc565b620002b4620006ce36600462004828565b62001b64565b60006001600160e01b0319821663112fc36360e01b1480620006fc5750620006fc8262001c79565b92915050565b6200071d6000805160206200833c83398151915233620012f1565b620007455760405162461bcd60e51b81526004016200073c9062004860565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b600054610100900460ff16158080156200077b5750600054600160ff909116105b80620007975750303b15801562000797575060005460ff166001145b620007b65760405162461bcd60e51b81526004016200073c90620048a1565b6000805460ff191660011790558015620007da576000805461ff0019166101001790555b620007e9868686868662000dcd565b801562000831576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200086b9190620048ef565b6040516020818303038152906040528051906020012081565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051339450909250620008d091508490602001620048ef565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000912929101620048ef565b604051602081830303815290604052805190602001208103620009495760405162461bcd60e51b81526004016200073c906200490d565b6001600160a01b038216620009a15760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374207265636569766572206164647265737300000000000060448201526064016200073c565b600081815260ce60205260409020546001600160a01b0316620009d85760405162461bcd60e51b81526004016200073c906200495d565b60008888604051602001620009ef92919062004994565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000a5357600080fd5b505af115801562000a68573d6000803e3d6000fd5b505050600082815260ce602052604090205462000a95915082906001600160a01b031689338a8a62001ca1565b505050505050505050565b60008281526065602052604090206001015462000abd8162002020565b62000ac983836200202f565b505050565b6001600160a01b038116331462000b405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016200073c565b62000b4c828262002055565b5050565b6000806001600160a01b031660ce6000858560405160200162000b7592919062004994565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060405133945090925062000bf991508490602001620048ef565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000c3b929101620048ef565b60405160208183030381529060405280519060200120810362000c725760405162461bcd60e51b81526004016200073c906200490d565b6001600160a01b03821662000cca5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374207265636569766572206164647265737300000000000060448201526064016200073c565b600081815260ce60205260409020546001600160a01b031662000d015760405162461bcd60e51b81526004016200073c906200495d565b60008a8a60405160200162000d1892919062004994565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000d7c57600080fd5b505af115801562000d91573d6000803e3d6000fd5b505050600082815260ce602052604090205462000dc0915082906001600160a01b03168b338c8c8c8c6200207b565b5050505050505050505050565b600054610100900460ff161580801562000dee5750600054600160ff909116105b8062000e0a5750303b15801562000e0a575060005460ff166001145b62000e295760405162461bcd60e51b81526004016200073c90620048a1565b6000805460ff19166001179055801562000e4d576000805461ff0019166101001790555b6001600160a01b03821662000ea55760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f2062652073657460448201526064016200073c565b62000eaf620024b5565b62000ebc60003362002524565b62000ed76000805160206200833c8339815191523362002524565b62000f037ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362002524565b8560405160200162000f169190620048ef565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562000831576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200162000828565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929262001035929101620048ef565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b1580156200108857600080fd5b505af11580156200109d573d6000803e3d6000fd5b50505050620011076040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620010d79190620048ef565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168733888888886200207b565b5050505050565b60c9546001600160a01b031633146200116a5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f78790000000060448201526064016200073c565b838360cc54821415801562001186575062001186828262002530565b620011d45760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f7272656374000000000060448201526064016200073c565b6000620011e28585620025bb565b90506000600982600e811115620011fd57620011fd620049a4565b14806200121e5750600a82600e8111156200121c576200121c620049a4565b145b1562001239576200123188878762002612565b9050620012c6565b600b82600e811115620012505762001250620049a4565b1480620012715750600c82600e8111156200126f576200126f620049a4565b145b1562001284576200123188878762002abc565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b60448201526064016200073c565b5050505050505050565b6000828152609760205260408120620012ea908362002f01565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b620013376000805160206200833c83398151915233620012f1565b620013565760405162461bcd60e51b81526004016200073c9062004860565b60cd805460ff60a01b19169055565b60006001600160a01b0389163014620013c15760405162461bcd60e51b815260206004820152601d60248201527f5265766572742045524331313535206261746368207472616e7366657200000060448201526064016200073c565b507fbc197c819b3e337a6f9652dd10becd7eef83032af3b9d958d3d42f669414662198975050505050505050565b60ca546001600160a01b031633148062001411575062001411600033620012f1565b620014575760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b60448201526064016200073c565b600082826040516020016200146e92919062004994565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316620014ed5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f7420736574000000000000000060448201526064016200073c565b600090815260ce6020526040902080546001600160a01b03191690555050565b620015397ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012f1565b620015875760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c4520697320726571756972656460448201526064016200073c565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa90620015bb9087908790600401620049ba565b602060405180830381865afa158015620015d9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015ff9190620049e9565b620016465760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b60448201526064016200073c565b6001600160a01b0381163b6200169f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e74726163740060448201526064016200073c565b60008484604051602001620016b692919062004994565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b0388811683529452919091205490925016156200173a5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b60448201526064016200073c565b6001600160a01b038216600090815260d0602052604090205460ff1615620017a55760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c726561647920616464656400000000000000000060448201526064016200073c565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917ff86f4b9b158b421a62f31d8b430c86afba56c6bb611fb82bc115dd030903d36a91a45050505050565b6000818152609760205260408120620006fc9062002f0f565b60ca546001600160a01b031633148062001861575062001861600033620012f1565b620018a75760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b60448201526064016200073c565b60008383604051602001620018be92919062004994565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316156200193e5760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c7265616479207365740000000060448201526064016200073c565b6001600160a01b038216620019675760405162461bcd60e51b81526004016200073c906200495d565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b600082815260656020526040902060010154620019b48162002020565b62000ac9838362002055565b620019cd600033620012f1565b62001a1b5760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c45206973207265717569726564000060448201526064016200073c565b6001600160a01b03811662001a735760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f2062652073657460448201526064016200073c565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038716301462001b385760405162461bcd60e51b815260206004820152601760248201527f5265766572742045524331313535207472616e7366657200000000000000000060448201526064016200073c565b507ff23a6e612e1ff4830e658fe43f4e3cb4a5f8170bd5d9e69fb5d7a7fa9e4fdf979695505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929262001ba9929101620048ef565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b15801562001bfc57600080fd5b505af115801562001c11573d6000803e3d6000fd5b5050505062000ac96040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001c4b9190620048ef565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168533868662001ca1565b60006001600160e01b03198216630271189760e51b1480620006fc5750620006fc8262002f1a565b600086815260d1602090815260408083206001600160a01b0380891685529252822054168062001d0f57506001600160a01b038516600090815260d06020526040902054859060ff161562001d0a5760405162461bcd60e51b81526004016200073c9062004a0d565b600191505b6001600160a01b0381163b62001d635760405162461bcd60e51b81526020600482015260186024820152772737903a37b5b2b71031b637b7329037b71039b1b430b4b760411b60448201526064016200073c565b60405163e985e9c560e01b81523360048201523060248201526001600160a01b0382169063e985e9c590604401602060405180830381865afa15801562001dae573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001dd49190620049e9565b62001e1e5760405162461bcd60e51b81526020600482015260196024820152782737ba1030b63637bbb2b21022a92198989a9a902a37b5b2b760391b60448201526064016200073c565b600062001e2e8787878762002f42565b9050821562001f41576040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001e699190620048ef565b60405160208183030381529060405280519060200120890362001ea05760405162461bcd60e51b81526004016200073c9062004a44565b62001eaf898333888862002fab565b905062001ed3898362001ec28862003073565b62001ecd8862003073565b620030bd565b604051637921219560e11b81526001600160a01b0383169063f242432a9062001f0790339030908a908a9060040162004a97565b600060405180830381600087803b15801562001f2257600080fd5b505af115801562001f37573d6000803e3d6000fd5b5050505062001fab565b604051637a94c56560e11b815233600482015260248101869052604481018590526001600160a01b0383169063f5298aca90606401600060405180830381600087803b15801562001f9157600080fd5b505af115801562001fa6573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001fe1908c908c90869060040162004acf565b600060405180830381600087803b15801562001ffc57600080fd5b505af115801562002011573d6000803e3d6000fd5b50505050505050505050505050565b6200202c8133620031c9565b50565b6200203b828262003238565b600082815260976020526040902062000ac99082620032c2565b620020618282620032d9565b600082815260976020526040902062000ac9908262003343565b600088815260d1602090815260408083206001600160a01b03808b16855292528220541680620020e957506001600160a01b038716600090815260d06020526040902054879060ff1615620020e45760405162461bcd60e51b81526004016200073c9062004a0d565b600191505b6001600160a01b0381163b6200213d5760405162461bcd60e51b81526020600482015260186024820152772737903a37b5b2b71031b637b7329037b71039b1b430b4b760411b60448201526064016200073c565b60405163e985e9c560e01b81523360048201523060248201526001600160a01b0382169063e985e9c590604401602060405180830381865afa15801562002188573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620021ae9190620049e9565b620021f85760405162461bcd60e51b81526020600482015260196024820152782737ba1030b63637bbb2b21022a92198989a9a902a37b5b2b760391b60448201526064016200073c565b60006200226b898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b9182918501908490808284376000920191909152506200335a92505050565b90508215620023d3576040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620022a69190620048ef565b604051602081830303815290604052805190602001208b03620022dd5760405162461bcd60e51b81526004016200073c9062004a44565b620022ee8b83338a8a8a8a620033a9565b9050620023618b8389898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b918291850190849080828437600092019190915250620030bd92505050565b604051631759616b60e11b81526001600160a01b03831690632eb2c2d6906200239990339030908c908c908c908c9060040162004b37565b600060405180830381600087803b158015620023b457600080fd5b505af1158015620023c9573d6000803e3d6000fd5b505050506200243e565b604051631ac8311560e21b81526001600160a01b03831690636b20c45490620024099033908b908b908b908b9060040162004b9a565b600060405180830381600087803b1580156200242457600080fd5b505af115801562002439573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062002474908e908e90869060040162004acf565b600060405180830381600087803b1580156200248f57600080fd5b505af1158015620024a4573d6000803e3d6000fd5b505050505050505050505050505050565b600054610100900460ff16620025225760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016200073c565b565b62000b4c82826200202f565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620025649190620048ef565b604051602081830303815290604052805190602001208314620025a457600083815260ce60205260409020546001600160a01b03838116911614620012ea565b5060cd546001600160a01b03908116911614919050565b600080620025cc83850185620041f1565b9050620025db60208262004be2565b6000036200260457620025fb620025f58483818862004c05565b620025bb565b915050620006fc565b620025fb8385018562004c46565b600080620026218484620025bb565b9050600080808080600986600e811115620026405762002640620049a4565b03620026c5576000620026548a8a6200352b565b90508060400151955080602001519450806060015193508060800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002882565b6000620026d38a8a620035e7565b9050806000015160400151955080600001516020015194508060000151606001519350806000015160800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b031603620028805760cd54600160a01b900460ff16620027c35760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c65640000000060448201526064016200073c565b602081015151604051620027d79062003f30565b620027e39190620043c9565b604051809103906000f08015801562002800573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918e917fae5aabebaedd1b95e68d95d1bc05734a63a8e451f94b37864515b78c532247d99190a45b505b600986600e811115620028995762002899620049a4565b148015620028ee57506040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620028d49190620048ef565b604051602081830303815290604052805190602001208a14155b801562002910575060008a815260d36020526040902062002910908562003689565b15620029d0576001600160a01b0384163b620029405760405162461bcd60e51b81526004016200073c9062004a0d565b620029628a85620029518662003073565b6200295c8662003073565b620036ac565b604051637921219560e11b81526001600160a01b0385169063f242432a906200299690309089908890889060040162004a97565b600060405180830381600087803b158015620029b157600080fd5b505af1158015620029c6573d6000803e3d6000fd5b5050505062002a4a565b60405163731133e960e01b81526001600160a01b0386811660048301526024820185905260448201849052608060648301526000608483015282169063731133e99060a401600060405180830381600087803b15801562002a3057600080fd5b505af115801562002a45573d6000803e3d6000fd5b505050505b806001600160a01b0316846001600160a01b03168b7f2349a6dafaf84dd371a44cd78bd587d9e750c3dfa1137d21f34f00e0d4babcb262002a8b8762003073565b62002a968762003073565b60405162002aa692919062004ca1565b60405180910390a4509298975050505050505050565b60008062002acb8484620025bb565b905060008060608082600b86600e81111562002aeb5762002aeb620049a4565b0362002b7057600062002aff8a8a620037b8565b90508060400151955080602001519450806060015193508060800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002d18565b600062002b7e8a8a62003879565b9050806000015160400151955080600001516020015194508060000151606001519350806000015160800151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b03160362002d165760cd54600160a01b900460ff1662002c6e5760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c65640000000060448201526064016200073c565b60208101515160405162002c829062003f30565b62002c8e9190620043c9565b604051809103906000f08015801562002cab573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a81168086529190935281842080546001600160a01b03191693861693841790559051939550909290918e917fae5aabebaedd1b95e68d95d1bc05734a63a8e451f94b37864515b78c532247d99190a45b505b600b86600e81111562002d2f5762002d2f620049a4565b14801562002d8457506040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162002d6a9190620048ef565b604051602081830303815290604052805190602001208a14155b801562002da6575060008a815260d36020526040902062002da6908562003689565b1562002e52576001600160a01b0384163b62002dd65760405162461bcd60e51b81526004016200073c9062004a0d565b62002de48a858585620036ac565b604051631759616b60e11b81526001600160a01b03851690632eb2c2d69062002e1890309089908890889060040162004cca565b600060405180830381600087803b15801562002e3357600080fd5b505af115801562002e48573d6000803e3d6000fd5b5050505062002eb9565b604051630fbfeffd60e11b81526001600160a01b03821690631f7fdffa9062002e849088908790879060040162004d29565b600060405180830381600087803b15801562002e9f57600080fd5b505af115801562002eb4573d6000803e3d6000fd5b505050505b806001600160a01b0316846001600160a01b03168b7f2349a6dafaf84dd371a44cd78bd587d9e750c3dfa1137d21f34f00e0d4babcb2868660405162002aa692919062004ca1565b6000620012ea838362003920565b6000620006fc825490565b60006001600160e01b03198216635a05180f60e01b1480620006fc5750620006fc826200394d565b6040805160c081018252600960a0820190815281526001600160a01b0380871660208084019190915290861682840152606080830186905260808301859052925162002f919183910162004ded565b604051602081830303815290604052915050949350505050565b600085815260d3602052604081206060919062002fc9908762003689565b90508062002ffe5762002fdd878762003984565b62002ff68686868662002ff08b62003a9d565b62003b2e565b91506200300f565b6200300c8686868662002f42565b91505b856001600160a01b0316877f601046fc8dbb772c2b88d30850532ffec5253f2e73c855af1c5f318a7a4562b0620030468762003073565b620030518762003073565b6040516200306192919062004ca1565b60405180910390a35095945050505050565b604080516001808252818301909252606091602080830190803683370190505090508181600081518110620030ac57620030ac62004dfd565b602002602001018181525050919050565b8051825114620031105760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206c656e677468206f662061727261797300000000000060448201526064016200073c565b60005b8251811015620011075781818151811062003132576200313262004dfd565b602002602001015160d260008781526020019081526020016000206000866001600160a01b03166001600160a01b03168152602001908152602001600020600085848151811062003187576200318762004dfd565b602002602001015181526020019081526020016000206000828254620031ae919062004e29565b90915550819050620031c08162004e3f565b91505062003113565b620031d58282620012f1565b62000b4c57620031f0816001600160a01b0316601462003bb5565b620031fd83602062003bb5565b6040516020016200321092919062004e5b565b60408051601f198184030181529082905262461bcd60e51b82526200073c91600401620043c9565b620032448282620012f1565b62000b4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200327e3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012ea836001600160a01b03841662003d6e565b620032e58282620012f1565b1562000b4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012ea836001600160a01b03841662003dc0565b6040805160c081018252600b60a0820190815281526001600160a01b0380871660208084019190915290861682840152606080830186905260808301859052925162002f919183910162004f3b565b600087815260d36020526040812060609190620033c7908962003689565b9050806200346157620033db898962003984565b62003459888888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152506200345392508f915062003a9d9050565b62003ec4565b9150620034d5565b620034d2888888888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152506200335a92505050565b91505b876001600160a01b0316897f601046fc8dbb772c2b88d30850532ffec5253f2e73c855af1c5f318a7a4562b08888888860405162003517949392919062004f50565b60405180910390a350979650505050505050565b6040805160c081018252600060a0820181815282526020820181905291810182905260608101829052608081019190915260096200356a8484620025bb565b600e8111156200357e576200357e620049a4565b14620035d95760405162461bcd60e51b8152602060048201526024808201527f4d6573736167652074797065206973206e6f742045524331313535207472616e60448201526339b332b960e11b60648201526084016200073c565b620012ea828401846200502b565b620035f162003f3e565b600a620035ff8484620025bb565b600e811115620036135762003613620049a4565b146200367b5760405162461bcd60e51b815260206004820152603060248201527f4d6573736167652074797065206973206e6f742045524331313535416e64546f60448201526f35b2b724b73337903a3930b739b332b960811b60648201526084016200073c565b620012ea8284018462005097565b6001600160a01b03811660009081526001830160205260408120541515620012ea565b8051825114620036ff5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206c656e677468206f662061727261797300000000000060448201526064016200073c565b60005b8251811015620011075781818151811062003721576200372162004dfd565b602002602001015160d260008781526020019081526020016000206000866001600160a01b03166001600160a01b03168152602001908152602001600020600085848151811062003776576200377662004dfd565b6020026020010151815260200190815260200160002060008282546200379d91906200511f565b90915550819050620037af8162004e3f565b91505062003702565b6040805160c081018252600060a082018181528252602082018190529181019190915260608082018190526080820152600b620037f68484620025bb565b600e8111156200380a576200380a620049a4565b146200386b5760405162461bcd60e51b815260206004820152602960248201527f4d6573736167652074797065206973206e6f7420455243313135354261746368604482015268103a3930b739b332b960b91b60648201526084016200073c565b620012ea8284018462005267565b6200388362003f97565b600c620038918484620025bb565b600e811115620038a557620038a5620049a4565b14620039125760405162461bcd60e51b815260206004820152603560248201527f4d6573736167652074797065206973206e6f742045524331313535426174636860448201527420b7322a37b5b2b724b73337903a3930b739b332b960591b60648201526084016200073c565b620012ea82840184620052a7565b60008260000182815481106200393a576200393a62004dfd565b9060005260206000200154905092915050565b60006001600160e01b03198216637965db0b60e01b1480620006fc57506301ffc9a760e01b6001600160e01b0319831614620006fc565b6001600160a01b0381163b620039dd5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e74726163740060448201526064016200073c565b600082815260d360205260409020620039f7908262003689565b1562003a465760405162461bcd60e51b815260206004820152601f60248201527f4552433131353520546f6b656e2077617320616c72656164792061646465640060448201526064016200073c565b600082815260d36020526040902062003a609082620032c2565b506040516000906001600160a01b0383169084907ff86f4b9b158b421a62f31d8b430c86afba56c6bb611fb82bc115dd030903d36a908490a45050565b6040805160208101909152606081526040805160208101918290526303a24d0760e21b90915260006024820152806001600160a01b038416630e89341c60448301600060405180830381865afa15801562003afc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262003b26919081019062005325565b905292915050565b604080516101008101825260609160009190819081018060e0830180600a81525081526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018781525081526020018481525090508060405160200162003b9a91906200539b565b60405160208183030381529060405291505095945050505050565b6060600062003bc6836002620053d7565b62003bd390600262004e29565b6001600160401b0381111562003bed5762003bed62004002565b6040519080825280601f01601f19166020018201604052801562003c18576020820181803683370190505b509050600360fc1b8160008151811062003c365762003c3662004dfd565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062003c685762003c6862004dfd565b60200101906001600160f81b031916908160001a905350600062003c8e846002620053d7565b62003c9b90600162004e29565b90505b600181111562003d1d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062003cd35762003cd362004dfd565b1a60f81b82828151811062003cec5762003cec62004dfd565b60200101906001600160f81b031916908160001a90535060049490941c9362003d1581620053f9565b905062003c9e565b508315620012ea5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016200073c565b600081815260018301602052604081205462003db757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620006fc565b506000620006fc565b6000818152600183016020526040812054801562003eb957600062003de76001836200511f565b855490915060009062003dfd906001906200511f565b905081811462003e6957600086600001828154811062003e215762003e2162004dfd565b906000526020600020015490508087600001848154811062003e475762003e4762004dfd565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003e7d5762003e7d62005413565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620006fc565b6000915050620006fc565b604080516101008101825260609160009190819081018060e0830180600c81525081526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018781525081526020018481525090508060405160200162003b9a919062005429565b612ecd806200546f83390190565b6040805161010081018252600060e08201818152928201928352606082018190526080820181905260a0820181905260c08201529081905b815260200162003f926040518060200160405280606081525090565b905290565b6040805161010081018252600060e082018181529282019283526060808301829052608083019190915260a0820181905260c082015290819062003f76565b60006020828403121562003fe957600080fd5b81356001600160e01b031981168114620012ea57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051602081016001600160401b03811182821017156200403d576200403d62004002565b60405290565b60405160a081016001600160401b03811182821017156200403d576200403d62004002565b604080519081016001600160401b03811182821017156200403d576200403d62004002565b604051601f8201601f191681016001600160401b0381118282101715620040b857620040b862004002565b604052919050565b60006001600160401b03821115620040dc57620040dc62004002565b50601f01601f191660200190565b600082601f830112620040fc57600080fd5b8135620041136200410d82620040c0565b6200408d565b8181528460208386010111156200412957600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b03811681146200202c57600080fd5b600080600080600060a086880312156200417557600080fd5b85356001600160401b038111156200418c57600080fd5b6200419a88828901620040ea565b9550506020860135620041ad8162004146565b93506040860135620041bf8162004146565b92506060860135620041d18162004146565b91506080860135620041e38162004146565b809150509295509295909350565b6000602082840312156200420457600080fd5b5035919050565b6000806000606084860312156200422157600080fd5b833592506020840135620042358162004146565b929592945050506040919091013590565b600080604083850312156200425a57600080fd5b8235915060208301356200426e8162004146565b809150509250929050565b60008083601f8401126200428c57600080fd5b5081356001600160401b03811115620042a457600080fd5b602083019150836020828501011115620042bd57600080fd5b9250929050565b600080600080600060808688031215620042dd57600080fd5b85356001600160401b03811115620042f457600080fd5b620043028882890162004279565b9096509450506020860135620043188162004146565b94979396509394604081013594506060013592915050565b600080602083850312156200434457600080fd5b82356001600160401b038111156200435b57600080fd5b620043698582860162004279565b90969095509350505050565b60005b838110156200439257818101518382015260200162004378565b50506000910152565b60008151808452620043b581602086016020860162004375565b601f01601f19169290920160200192915050565b602081526000620012ea60208301846200439b565b60008083601f840112620043f157600080fd5b5081356001600160401b038111156200440957600080fd5b6020830191508360208260051b8501011115620042bd57600080fd5b60008060008060008060006080888a0312156200444157600080fd5b87356001600160401b03808211156200445957600080fd5b620044678b838c0162004279565b909950975060208a013591506200447e8262004146565b909550604089013590808211156200449557600080fd5b620044a38b838c01620043de565b909650945060608a0135915080821115620044bd57600080fd5b50620044cc8a828b01620043de565b989b979a50959850939692959293505050565b600080600080600060608688031215620044f857600080fd5b8535620045058162004146565b945060208601356001600160401b03808211156200452257600080fd5b6200453089838a01620043de565b909650945060408801359150808211156200454a57600080fd5b506200455988828901620043de565b969995985093965092949392505050565b600080600080606085870312156200458157600080fd5b843593506020850135620045958162004146565b925060408501356001600160401b03811115620045b157600080fd5b620045bf8782880162004279565b95989497509550505050565b60008060408385031215620045df57600080fd5b50508035926020909101359150565b6000602082840312156200460157600080fd5b8135620012ea8162004146565b60008060008060008060008060a0898b0312156200462b57600080fd5b8835620046388162004146565b975060208901356200464a8162004146565b965060408901356001600160401b03808211156200466757600080fd5b620046758c838d01620043de565b909850965060608b01359150808211156200468f57600080fd5b6200469d8c838d01620043de565b909650945060808b0135915080821115620046b757600080fd5b50620046c68b828c0162004279565b999c989b5096995094979396929594505050565b60008060008060608587031215620046f157600080fd5b84356001600160401b038111156200470857600080fd5b620047168782880162004279565b90955093505060208501356200472c8162004146565b915060408501356200473e8162004146565b939692955090935050565b6000806000604084860312156200475f57600080fd5b83356001600160401b038111156200477657600080fd5b620047848682870162004279565b90945092505060208401356200479a8162004146565b809150509250925092565b60008060008060008060a08789031215620047bf57600080fd5b8635620047cc8162004146565b95506020870135620047de8162004146565b9450604087013593506060870135925060808701356001600160401b038111156200480857600080fd5b6200481689828a0162004279565b979a9699509497509295939492505050565b6000806000606084860312156200483e57600080fd5b83356200484b8162004146565b95602085013595506040909401359392505050565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b600082516200490381846020870162004375565b9190910192915050565b60208082526030908201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560408201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606082015260800190565b6020808252601f908201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604082015260600190565b8183823760009101908152919050565b634e487b7160e01b600052602160045260246000fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600060208284031215620049fc57600080fd5b81518015158114620012ea57600080fd5b6020808252601a908201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604082015260600190565b60208082526033908201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604082015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b8381526001600160a01b038316602082015260606040820181905260009062004afb908301846200439b565b95945050505050565b81835260006001600160fb1b0383111562004b1e57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0387811682528616602082015260a06040820181905260009062004b66908301868862004b04565b828103606084015262004b7b81858762004b04565b8381036080909401939093525050600081526020019695505050505050565b6001600160a01b038616815260606020820181905260009062004bc1908301868862004b04565b828103604084015262004bd681858762004b04565b98975050505050505050565b60008262004c0057634e487b7160e01b600052601260045260246000fd5b500690565b6000808585111562004c1657600080fd5b8386111562004c2457600080fd5b5050820193919092039150565b8035600f811062004c4157600080fd5b919050565b60006020828403121562004c5957600080fd5b620012ea8262004c31565b600081518084526020808501945080840160005b8381101562004c965781518752958201959082019060010162004c78565b509495945050505050565b60408152600062004cb6604083018562004c64565b828103602084015262004afb818562004c64565b6001600160a01b0385811682528416602082015260a06040820181905260009062004cf89083018562004c64565b828103606084015262004d0c818562004c64565b838103608090940193909352505060008152602001949350505050565b6001600160a01b038416815260806020820181905260009062004d4f9083018562004c64565b828103604084015262004d63818562004c64565b8381036060909401939093525050600081526020019392505050565b8051600f811062004da057634e487b7160e01b600052602160045260246000fd5b90915250565b62004db382825162004d7f565b6020818101516001600160a01b03908116918401919091526040808301519091169083015260608082015190830152608090810151910152565b60a08101620006fc828462004da6565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115620006fc57620006fc62004e13565b60006001820162004e545762004e5462004e13565b5060010190565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162004e9581601785016020880162004375565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162004ec881602884016020880162004375565b01602801949350505050565b62004ee182825162004d7f565b6000602082015160018060a01b0380821660208601528060408501511660408601525050606082015160a0606085015262004f2060a085018262004c64565b90506080830151848203608086015262004afb828262004c64565b602081526000620012ea602083018462004ed4565b60408152600062004f6660408301868862004b04565b828103602084015262004f7b81858762004b04565b979650505050505050565b60006020828403121562004f9957600080fd5b62004fa362004018565b905062004fb08262004c31565b815292915050565b600060a0828403121562004fcb57600080fd5b62004fd562004043565b905062004fe3838362004f86565b8152602082013562004ff58162004146565b602082015260408201356200500a8162004146565b80604083015250606082013560608201526080820135608082015292915050565b600060a082840312156200503e57600080fd5b620012ea838362004fb8565b6000602082840312156200505d57600080fd5b6200506762004018565b905081356001600160401b038111156200508057600080fd5b6200508e84828501620040ea565b82525092915050565b600060208284031215620050aa57600080fd5b81356001600160401b0380821115620050c257600080fd5b9083019060c08286031215620050d757600080fd5b620050e162004068565b620050ed868462004fb8565b815260a0830135828111156200510257600080fd5b62005110878286016200504a565b60208301525095945050505050565b81810381811115620006fc57620006fc62004e13565b600082601f8301126200514757600080fd5b813560206001600160401b0382111562005165576200516562004002565b8160051b620051768282016200408d565b92835284810182019282810190878511156200519157600080fd5b83870192505b8483101562004f7b5782358252918301919083019062005197565b600060a08284031215620051c557600080fd5b620051cf62004043565b9050620051dd838362004f86565b81526020820135620051ef8162004146565b60208201526040820135620052048162004146565b604082015260608201356001600160401b03808211156200522457600080fd5b620052328583860162005135565b606084015260808401359150808211156200524c57600080fd5b506200525b8482850162005135565b60808301525092915050565b6000602082840312156200527a57600080fd5b81356001600160401b038111156200529157600080fd5b6200529f84828501620051b2565b949350505050565b600060208284031215620052ba57600080fd5b81356001600160401b0380821115620052d257600080fd5b9083019060408286031215620052e757600080fd5b620052f162004068565b8235828111156200530157600080fd5b6200530f87828601620051b2565b8252506020830135828111156200510257600080fd5b6000602082840312156200533857600080fd5b81516001600160401b038111156200534f57600080fd5b8201601f810184136200536157600080fd5b8051620053726200410d82620040c0565b8181528560208385010111156200538857600080fd5b62004afb82602083016020860162004375565b60208152620053af60208201835162004da6565b6000602083015160c08084015280519050602060e08401526200529f6101008401826200439b565b6000816000190483118215151615620053f457620053f462004e13565b500290565b6000816200540b576200540b62004e13565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60208152600082516040602084015262005447606084018262004ed4565b602085810151858303601f190160408701525181835291925062004afb908301826200439b56fe60806040523480156200001157600080fd5b5060405162002ecd38038062002ecd8339810160408190526200003491620004ed565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d760201b620009121760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e660201b620009211760201c565b6200013d826200024460201b6200094a1760201c565b62000152620001e660201b620009211760201c565b6200016d60008051602062002ead83398151915280620002ae565b6200018860008051602062002ead83398151915233620002f9565b8015620001cf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50506200071c565b6001600160a01b03163b151590565b600054610100900460ff16620002425760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a05760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab8162000309565b50565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b62000305828262000370565b5050565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002e8d83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ab81620003b3565b620003878282620003c160201b6200097d1760201c565b6000828152609760209081526040909120620003ae91839062000a0362000465821b17901c565b505050565b60cb62000305828262000650565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620003055760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004213390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200047c836001600160a01b03841662000485565b90505b92915050565b6000818152600183016020526040812054620004ce575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200047f565b5060006200047f565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156200050157600080fd5b82516001600160401b03808211156200051957600080fd5b818501915085601f8301126200052e57600080fd5b815181811115620005435762000543620004d7565b604051601f8201601f19908116603f011681019083821181831017156200056e576200056e620004d7565b8160405282815288868487010111156200058757600080fd5b600093505b82841015620005ab57848401860151818501870152928501926200058c565b600086848301015280965050505050505092915050565b600181811c90821680620005d757607f821691505b602082108103620005f857634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003ae57600081815260208120601f850160051c81016020861015620006275750805b601f850160051c820191505b81811015620006485782815560010162000633565b505050505050565b81516001600160401b038111156200066c576200066c620004d7565b62000684816200067d8454620005c2565b84620005fe565b602080601f831160018114620006bc5760008415620006a35750858301515b600019600386901b1c1916600185901b17855562000648565b600085815260208120601f198616915b82811015620006ed57888601518255948401946001909101908401620006cc565b50858210156200070c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612761806200072c6000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063731133e9116100b8578063ca15c8731161007c578063ca15c873146102b4578063d5391393146102c7578063d547741f146102ee578063e985e9c514610301578063f242432a1461033d578063f5298aca1461035057600080fd5b8063731133e9146102485780639010d07c1461025b57806391d1485414610286578063a217fddf14610299578063a22cb465146102a157600080fd5b80632eb2c2d6116100ff5780632eb2c2d6146101dc5780632f2ff15d146101ef57806336568abe146102025780634e1273f4146102155780636b20c4541461023557600080fd5b8062fdd58e1461013b57806301ffc9a7146101615780630e89341c146101845780631f7fdffa146101a4578063248a9ca3146101b9575b600080fd5b61014e610149366004611a1f565b610363565b6040519081526020015b60405180910390f35b61017461016f366004611a5f565b6103fe565b6040519015158152602001610158565b610197610192366004611a7c565b610409565b6040516101589190611ae5565b6101b76101b2366004611c41565b61049d565b005b61014e6101c7366004611a7c565b60009081526065602052604090206001015490565b6101b76101ea366004611cd9565b61051e565b6101b76101fd366004611d82565b61056a565b6101b7610210366004611d82565b610594565b610228610223366004611dae565b610612565b6040516101589190611eb3565b6101b7610243366004611ec6565b61073b565b6101b7610256366004611f39565b61077e565b61026e610269366004611f8d565b6107f9565b6040516001600160a01b039091168152602001610158565b610174610294366004611d82565b610818565b61014e600081565b6101b76102af366004611faf565b610843565b61014e6102c2366004611a7c565b61084e565b61014e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101b76102fc366004611d82565b610865565b61017461030f366004611feb565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205460ff1690565b6101b761034b366004612015565b61088a565b6101b761035e366004612079565b6108cf565b60006001600160a01b0383166103d35760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b50600081815260c9602090815260408083206001600160a01b03861684529091529020545b92915050565b60006103f882610a18565b606060cb8054610418906120ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610444906120ac565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b50505050509050919050565b6104c77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b61050c5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610a58565b50505050565b6001600160a01b03851633148061053a575061053a853361030f565b6105565760405162461bcd60e51b81526004016103ca906120e6565b6105638585858585610ba4565b5050505050565b60008281526065602052604090206001015461058581610d43565b61058f8383610d4d565b505050565b6001600160a01b03811633146106045760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016103ca565b61060e8282610d6f565b5050565b606081518351146106775760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016103ca565b600083516001600160401b0381111561069257610692611af8565b6040519080825280602002602001820160405280156106bb578160200160208202803683370190505b50905060005b8451811015610733576107068582815181106106df576106df612135565b60200260200101518583815181106106f9576106f9612135565b6020026020010151610363565b82828151811061071857610718612135565b602090810291909101015261072c81612161565b90506106c1565b509392505050565b6001600160a01b0383163314806107575750610757833361030f565b6107735760405162461bcd60e51b81526004016103ca906120e6565b61058f838383610d91565b6107a87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610818565b6107ed5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b60448201526064016103ca565b61051884848484610f1e565b60008281526097602052604081206108119083610ffa565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61060e338383611006565b60008181526097602052604081206103f8906110e6565b60008281526065602052604090206001015461088081610d43565b61058f8383610d6f565b6001600160a01b0385163314806108a657506108a6853361030f565b6108c25760405162461bcd60e51b81526004016103ca906120e6565b61056385858585856110f0565b6001600160a01b0383163314806108eb57506108eb833361030f565b6109075760405162461bcd60e51b81526004016103ca906120e6565b61058f83838361121e565b6001600160a01b03163b151590565b600054610100900460ff166109485760405162461bcd60e51b81526004016103ca9061217a565b565b600054610100900460ff166109715760405162461bcd60e51b81526004016103ca9061217a565b61097a81611325565b50565b6109878282610818565b61060e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556109bf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610811836001600160a01b038416611355565b60006001600160e01b03198216636cdb3d1360e11b1480610a4957506001600160e01b031982166303a24d0760e21b145b806103f857506103f8826113a4565b6001600160a01b038416610a7e5760405162461bcd60e51b81526004016103ca906121c5565b8151835114610a9f5760405162461bcd60e51b81526004016103ca90612206565b3360005b8451811015610b3c57838181518110610abe57610abe612135565b602002602001015160c96000878481518110610adc57610adc612135565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254610b24919061224e565b90915550819050610b3481612161565b915050610aa3565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610b8d929190612261565b60405180910390a4610563816000878787876113c9565b8151835114610bc55760405162461bcd60e51b81526004016103ca90612206565b6001600160a01b038416610beb5760405162461bcd60e51b81526004016103ca9061228f565b3360005b8451811015610cd5576000858281518110610c0c57610c0c612135565b602002602001015190506000858381518110610c2a57610c2a612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038e168352909352919091205490915081811015610c7b5760405162461bcd60e51b81526004016103ca906122d4565b600083815260c9602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290610cba90849061224e565b9250508190555050505080610cce90612161565b9050610bef565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d25929190612261565b60405180910390a4610d3b8187878787876113c9565b505050505050565b61097a8133611524565b610d57828261097d565b600082815260976020526040902061058f9082610a03565b610d798282611588565b600082815260976020526040902061058f90826115ef565b6001600160a01b038316610db75760405162461bcd60e51b81526004016103ca9061231e565b8051825114610dd85760405162461bcd60e51b81526004016103ca90612206565b604080516020810190915260009081905233905b8351811015610eb1576000848281518110610e0957610e09612135565b602002602001015190506000848381518110610e2757610e27612135565b602090810291909101810151600084815260c9835260408082206001600160a01b038c168352909352919091205490915081811015610e785760405162461bcd60e51b81526004016103ca90612361565b600092835260c9602090815260408085206001600160a01b038b1686529091529092209103905580610ea981612161565b915050610dec565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051610f02929190612261565b60405180910390a4604080516020810190915260009052610518565b6001600160a01b038416610f445760405162461bcd60e51b81526004016103ca906121c5565b336000610f5085611604565b90506000610f5d85611604565b9050600086815260c9602090815260408083206001600160a01b038b16845290915281208054879290610f9190849061224e565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610ff18360008989898961164f565b50505050505050565b6000610811838361170a565b816001600160a01b0316836001600160a01b0316036110795760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016103ca565b6001600160a01b03838116600081815260ca6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006103f8825490565b6001600160a01b0384166111165760405162461bcd60e51b81526004016103ca9061228f565b33600061112285611604565b9050600061112f85611604565b9050600086815260c9602090815260408083206001600160a01b038c168452909152902054858110156111745760405162461bcd60e51b81526004016103ca906122d4565b600087815260c9602090815260408083206001600160a01b038d8116855292528083208985039055908a168252812080548892906111b390849061224e565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611213848a8a8a8a8a61164f565b505050505050505050565b6001600160a01b0383166112445760405162461bcd60e51b81526004016103ca9061231e565b33600061125084611604565b9050600061125d84611604565b604080516020808201835260009182905288825260c981528282206001600160a01b038b16835290522054909150848110156112ab5760405162461bcd60e51b81526004016103ca90612361565b600086815260c9602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4604080516020810190915260009052610ff1565b600054610100900460ff1661134c5760405162461bcd60e51b81526004016103ca9061217a565b61097a81611734565b600081815260018301602052604081205461139c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103f8565b5060006103f8565b60006001600160e01b03198216635a05180f60e01b14806103f857506103f882611740565b6001600160a01b0384163b15610d3b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061140d90899089908890889088906004016123a5565b6020604051808303816000875af1925050508015611448575060408051601f3d908101601f1916820190925261144591810190612403565b60015b6114f457611454612420565b806308c379a00361148d575061146861243c565b80611473575061148f565b8060405162461bcd60e51b81526004016103ca9190611ae5565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016103ca565b6001600160e01b0319811663bc197c8160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b61152e8282610818565b61060e57611546816001600160a01b03166014611775565b611551836020611775565b60405160200161156292919061250d565b60408051601f198184030181529082905262461bcd60e51b82526103ca91600401611ae5565b6115928282610818565b1561060e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610811836001600160a01b038416611910565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061163e5761163e612135565b602090810291909101015292915050565b6001600160a01b0384163b15610d3b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906116939089908990889088908890600401612582565b6020604051808303816000875af19250505080156116ce575060408051601f3d908101601f191682019092526116cb91810190612403565b60015b6116da57611454612420565b6001600160e01b0319811663f23a6e6160e01b14610ff15760405162461bcd60e51b81526004016103ca906124c5565b600082600001828154811061172157611721612135565b9060005260206000200154905092915050565b60cb61060e828261260d565b60006001600160e01b03198216637965db0b60e01b14806103f857506301ffc9a760e01b6001600160e01b03198316146103f8565b606060006117848360026126cc565b61178f90600261224e565b6001600160401b038111156117a6576117a6611af8565b6040519080825280601f01601f1916602001820160405280156117d0576020820181803683370190505b509050600360fc1b816000815181106117eb576117eb612135565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061181a5761181a612135565b60200101906001600160f81b031916908160001a905350600061183e8460026126cc565b61184990600161224e565b90505b60018111156118c1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061187d5761187d612135565b1a60f81b82828151811061189357611893612135565b60200101906001600160f81b031916908160001a90535060049490941c936118ba816126eb565b905061184c565b5083156108115760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016103ca565b600081815260018301602052604081205480156119f9576000611934600183612702565b855490915060009061194890600190612702565b90508181146119ad57600086600001828154811061196857611968612135565b906000526020600020015490508087600001848154811061198b5761198b612135565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119be576119be612715565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103f8565b60009150506103f8565b80356001600160a01b0381168114611a1a57600080fd5b919050565b60008060408385031215611a3257600080fd5b611a3b83611a03565b946020939093013593505050565b6001600160e01b03198116811461097a57600080fd5b600060208284031215611a7157600080fd5b813561081181611a49565b600060208284031215611a8e57600080fd5b5035919050565b60005b83811015611ab0578181015183820152602001611a98565b50506000910152565b60008151808452611ad1816020860160208601611a95565b601f01601f19169290920160200192915050565b6020815260006108116020830184611ab9565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715611b3357611b33611af8565b6040525050565b60006001600160401b03821115611b5357611b53611af8565b5060051b60200190565b600082601f830112611b6e57600080fd5b81356020611b7b82611b3a565b604051611b888282611b0e565b83815260059390931b8501820192828101915086841115611ba857600080fd5b8286015b84811015611bc35780358352918301918301611bac565b509695505050505050565b600082601f830112611bdf57600080fd5b81356001600160401b03811115611bf857611bf8611af8565b604051611c0f601f8301601f191660200182611b0e565b818152846020838601011115611c2457600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611c5757600080fd5b611c6085611a03565b935060208501356001600160401b0380821115611c7c57600080fd5b611c8888838901611b5d565b94506040870135915080821115611c9e57600080fd5b611caa88838901611b5d565b93506060870135915080821115611cc057600080fd5b50611ccd87828801611bce565b91505092959194509250565b600080600080600060a08688031215611cf157600080fd5b611cfa86611a03565b9450611d0860208701611a03565b935060408601356001600160401b0380821115611d2457600080fd5b611d3089838a01611b5d565b94506060880135915080821115611d4657600080fd5b611d5289838a01611b5d565b93506080880135915080821115611d6857600080fd5b50611d7588828901611bce565b9150509295509295909350565b60008060408385031215611d9557600080fd5b82359150611da560208401611a03565b90509250929050565b60008060408385031215611dc157600080fd5b82356001600160401b0380821115611dd857600080fd5b818501915085601f830112611dec57600080fd5b81356020611df982611b3a565b604051611e068282611b0e565b83815260059390931b8501820192828101915089841115611e2657600080fd5b948201945b83861015611e4b57611e3c86611a03565b82529482019490820190611e2b565b96505086013592505080821115611e6157600080fd5b50611e6e85828601611b5d565b9150509250929050565b600081518084526020808501945080840160005b83811015611ea857815187529582019590820190600101611e8c565b509495945050505050565b6020815260006108116020830184611e78565b600080600060608486031215611edb57600080fd5b611ee484611a03565b925060208401356001600160401b0380821115611f0057600080fd5b611f0c87838801611b5d565b93506040860135915080821115611f2257600080fd5b50611f2f86828701611b5d565b9150509250925092565b60008060008060808587031215611f4f57600080fd5b611f5885611a03565b9350602085013592506040850135915060608501356001600160401b03811115611f8157600080fd5b611ccd87828801611bce565b60008060408385031215611fa057600080fd5b50508035926020909101359150565b60008060408385031215611fc257600080fd5b611fcb83611a03565b915060208301358015158114611fe057600080fd5b809150509250929050565b60008060408385031215611ffe57600080fd5b61200783611a03565b9150611da560208401611a03565b600080600080600060a0868803121561202d57600080fd5b61203686611a03565b945061204460208701611a03565b9350604086013592506060860135915060808601356001600160401b0381111561206d57600080fd5b611d7588828901611bce565b60008060006060848603121561208e57600080fd5b61209784611a03565b95602085013595506040909401359392505050565b600181811c908216806120c057607f821691505b6020821081036120e057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602f908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526e195c881b9bdc88185c1c1c9bdd9959608a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016121735761217361214b565b5060010190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b808201808211156103f8576103f861214b565b6040815260006122746040830185611e78565b82810360208401526122868185611e78565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526023908201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526024908201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604082015263616e636560e01b606082015260800190565b6001600160a01b0386811682528516602082015260a0604082018190526000906123d190830186611e78565b82810360608401526123e38186611e78565b905082810360808401526123f78185611ab9565b98975050505050505050565b60006020828403121561241557600080fd5b815161081181611a49565b600060033d11156124395760046000803e5060005160e01c5b90565b600060443d101561244a5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561247957505050505090565b82850191508151818111156124915750505050505090565b843d87010160208285010111156124ab5750505050505090565b6124ba60208286010187611b0e565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612545816017850160208801611a95565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612576816028840160208801611a95565b01602801949350505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906125bc90830184611ab9565b979650505050505050565b601f82111561058f57600081815260208120601f850160051c810160208610156125ee5750805b601f850160051c820191505b81811015610d3b578281556001016125fa565b81516001600160401b0381111561262657612626611af8565b61263a8161263484546120ac565b846125c7565b602080601f83116001811461266f57600084156126575750858301515b600019600386901b1c1916600185901b178555610d3b565b600085815260208120601f198616915b8281101561269e5788860151825594840194600190910190840161267f565b50858210156126bc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008160001904831182151516156126e6576126e661214b565b500290565b6000816126fa576126fa61214b565b506000190190565b818103818111156103f8576103f861214b565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d84f746f173a737e6816e4123648488df6b8e119ec4b4fc93237fc9c098d976b64736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220cfd36f26d92e9c9eae1566679e3ea81f70e53e42b6fbaac0130e6c239bbfa4b264736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xD2Aaa00700000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x1eccbef867e0151b4ddefb7c128882a0ac4d7d575f345a7ab3163e06ebd006b3": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa007d2000000000000000000000000000000", + "0x47736bbadbc65fec4e9894f6984d0d491e5facb89fd0204c5bcbd48a0452db9c": "0x01", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x754cf444c02c0b79bbed2e953faf9e21907f39e80a440400e7c80172787bbc20": "0x01", + "0x81bcdf06b56c0ed62a68a6ae231e66722c27e6665c84ec0015693a6d86f2bb93": "0x01", + "0x95ba35dfc563b3cdf22c5d10aa0c0fbf467d8c69772f0713bf10d1fd4c418d90": "0x01", + "0x9c555ab2ae7e03723af9091d21cc41f5624390bd2faa37e68f82ec10b3f4cdb1": "0xd2aaa00400000000000000000000000000000000", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc3c8c7e4fab505d509bd381fc6e46feb8541ec60cbf617fe952ca0ec2b020b85": "0x01", + "0xcc": "0x455243323020457468657220436c6f6e65000000000000000000000000000022", + "0xcd": "0x4554484300000000000000000000000000000000000000000000000000000008", + "0xce": "0x12", + "0xde30f4d495db611e618274dc6e192bbf601fe6a22d1d6868c23aecfe97ee7daa": "0xd2aaa00400000000000000000000000000000000" + } + }, + "0xD2aAA00500000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x023e53b1d9fc4e87c67ca049b99030449c5fbc30fe2ba2dfd40c8ebf2b707219": "0x01", + "0x0c94570da19dff961fa301fdf83b467d2e96da7a41ee6dcc5c5f7ac33c270b8b": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x122f7d0619a5264c086c6547bffab20578c9fbf87522e041783d5d44beb2d25a": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa005d2000000000000000000000000000000", + "0x61d8ad11edb7edad4d8f3ba4ddc5c23ce790dfa64f07c35f257dc56cb7ce507b": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x6c8f1a70270c11627beb08e2afcc680f7fe60ee60ea538c3e5de154847fa0d8a": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0xab43ffaff5e7c8ac5804cdf58088ef28e1a2d3687a8068be710e369f38e47925": "0x01", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc9": "0xd2aaa00100000000000000000000000000000000", + "0xca": "0xd2aaa00800000000000000000000000000000000", + "0xcb": "0xd2aaa00300000000000000000000000000000000", + "0xcc": "0x5d625e25b9f1ef5d5b3778887e76df4fd02824a86b9d6138d7412f3305ac3813", + "0xcd": "0xd200000000000000000000000000000000000002", + "0xd65aeee08c5cda0d1c500775ee0d4d0a0db5bc751bbb2e734d1fda5833a58367": "0x01", + "0xff78f509c1fad38363f9cc13c767e3dece5b063d058a35423eb295bed984e41d": "0x01" + } + }, + "0xD2aAA00800000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x20759465fbe5069458376de22dca36115f7764f542021c0bcbb78bf61aa09a72": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa008d2000000000000000000000000000000", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x9f317a486a760376f442be8935e13e57c3862d8610cd990c8edc8bced4260a8c": "0x01", + "0xa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fb": "0xd2aaa00400000000000000000000000000000000", + "0xa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fc": "0xd2aaa00500000000000000000000000000000000", + "0xa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fd": "0xd2aaa00600000000000000000000000000000000", + "0xa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fe": "0xd2aaa00900000000000000000000000000000000", + "0xa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06ff": "0xd2aaa00a00000000000000000000000000000000", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc9": "0xd2aaa00100000000000000000000000000000000", + "0xca": "0xd200000000000000000000000000000000000005", + "0xcb": "0x05", + "0xcfcfe17ef148a3d0c82e4ec70086a0e7c4d7d50ee3e0c7407edbc18c05d5ea0f": "0x01", + "0xfbdf3ae60affa28bc7bb164fb6a710dee213469b9b78699f6891be35d9fb6bf4": "0x01" + } + }, + "0xD2aaA003d2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806359315792116100f9578063bbb9267811610097578063d547741f11610071578063d547741f146103f8578063eb0eb8ab1461040b578063f0cfb52e1461042e578063f34822b41461044e57600080fd5b8063bbb92678146103ab578063bbc4e8c2146103be578063ca15c873146103e557600080fd5b80639010d07c116100d35780639010d07c1461037457806391d1485414610387578063a217fddf1461039a578063aebc4bc3146103a257600080fd5b8063593157921461033b5780637304b44d1461034e578063884cee5a1461036157600080fd5b80632f2ff15d1161016657806345ee13821161014057806345ee1382146102c25780634fe5187c146102ca57806350f44280146102f55780635573b8b61461032857600080fd5b80632f2ff15d1461029157806336568abe146102a65780633b690b6b146102b957600080fd5b8063248a9ca3116101a2578063248a9ca31461024a57806328c5e1821461026d5780632d448928146102755780632dc151de1461027e57600080fd5b806301ffc9a7146101c957806314a7eaf6146101f157806314d140b01461021f575b600080fd5b6101dc6101d7366004611837565b610461565b60405190151581526020015b60405180910390f35b6102116101ff366004611861565b60d26020526000908152604090205481565b6040519081526020016101e8565b60cb54610232906001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b610211610258366004611861565b60009081526065602052604090206001015490565b61021161048c565b61021160d15481565b60ca54610232906001600160a01b031681565b6102a461029f36600461188f565b6104d5565b005b6102a46102b436600461188f565b6104ff565b61021160cc5481565b6102a4610582565b6102116102d836600461188f565b60d360209081526000928352604080842090915290825290205481565b61031b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516101e891906118e3565b60c954610232906001600160a01b031681565b6102a461034936600461188f565b610633565b6102a461035c366004611978565b6108e8565b6102a461036f366004611a25565b610a1c565b610232610382366004611aae565b610d76565b6101dc61039536600461188f565b610d95565b610211600081565b61021160d05481565b6102a46103b9366004611b5d565b610dc0565b6102117f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c81565b6102116103f3366004611861565b610f40565b6102a461040636600461188f565b610f57565b6101dc610419366004611ba2565b60ce6020526000908152604090205460ff1681565b61021161043c366004611ba2565b60cf6020526000908152604090205481565b6102a461045c366004611bbf565b610f7c565b60006001600160e01b03198216635a05180f60e01b14806104865750610486826111bd565b92915050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016104bc9190611c34565b6040516020818303038152906040528051906020012081565b6000828152606560205260409020600101546104f0816111f2565b6104fa83836111ff565b505050565b6001600160a01b03811633146105745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61057e8282611221565b5050565b61058d600033610d95565b6105cc5760405162461bcd60e51b815260206004820152601060248201526f24b731b7b93932b1ba1039b2b73232b960811b604482015260640161056b565b60cd5460d260006040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016106039190611c34565b6040516020818303038152906040528051906020012081526020019081526020016000208190555060cd60009055565b600082815260d3602090815260408083206001600160a01b03851684528252918290205482518084018452600781526613585a5b9b995d60ca1b818401529251859385936106819201611c34565b604051602081830303815290604052805190602001208303610720576001600160a01b038216600090815260ce602052604090205460ff166107055760405162461bcd60e51b815260206004820152601860248201527f526563697069656e74206d757374206265206163746976650000000000000000604482015260640161056b565b506001600160a01b038116600090815260cf60205260409020545b600083815260d26020526040902054429061073b9083611c66565b106107885760405162461bcd60e51b815260206004820152601b60248201527f4578636565646564206d6573736167652072617465206c696d69740000000000604482015260640161056b565b60ca546040516374a9e4c960e11b81523360048201526001600160a01b039091169063e953c99290602401602060405180830381865afa1580156107d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f49190611c87565b61084f5760405162461bcd60e51b815260206004820152602660248201527f53656e646572206973206e6f74207265676973746572656420746f6b656e206d60448201526530b730b3b2b960d11b606482015260840161056b565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200161087f9190611c34565b6040516020818303038152906040528051906020012085036108bb576001600160a01b038416600090815260cf602052604090204290556108e1565b600085815260d3602090815260408083206001600160a01b038816845290915290204290555b5050505050565b60d15482116109455760405162461bcd60e51b815260206004820152602360248201527f4761732070726963652074696d657374616d7020616c726561647920757064616044820152621d195960ea1b606482015260840161056b565b428211156109a35760405162461bcd60e51b815260206004820152602560248201527f54696d657374616d702073686f756c64206e6f7420626520696e207468652066604482015264757475726560d81b606482015260840161056b565b6040516e4d61696e6e6574476173507269636560881b6020820152602f0160408051601f19818403018152828252805160209182012060d0548452908301869052917fd9f6bd2abae0f2a51b3f5ffb29e0e35ee9ad2e3921ede0d71bff21dc8609f6f1910160405180910390a25060d09190915560d155565b60c9546001600160a01b03163314610a765760405162461bcd60e51b815260206004820152601d60248201527f53656e646572206973206e6f742061206d6573736167652070726f7879000000604482015260640161056b565b60cb546001600160a01b03848116911614610ad35760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206d75737420626520436f6d6d756e697479506f6f6c00000000604482015260640161056b565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610b039190611c34565b604051602081830303815290604052805190602001208414610b715760405162461bcd60e51b815260206004820152602160248201527f536f7572636520636861696e206e616d65206d757374206265204d61696e6e656044820152601d60fa1b606482015260840161056b565b6000610b7d8383611243565b9050600781600e811115610b9357610b93611ca4565b14610bf45760405162461bcd60e51b815260206004820152602b60248201527f546865206d6573736167652073686f756c6420636f6e7461696e20612073746160448201526a3a3ab99037b3103ab9b2b960a91b606482015260840161056b565b6000610c00848461128e565b6040808201516020808401516001600160a01b0316600090815260ce9091529190912054919250151560ff909116151503610c8c5760405162461bcd60e51b815260206004820152602660248201527f4163746976652075736572207374617475736573206d7573742062652064696660448201526519995c995b9d60d21b606482015260840161056b565b604081810180516020808501516001600160a01b0316600090815260ce90915292909220805460ff1916921515929092179091555115610d1c577fdacccea96400d48c51a00ff7af4d1c6b6ac4909bbff0fe495f0e0edc298c3dde60cc548260200151604051610d0f9291909182526001600160a01b0316602082015260400190565b60405180910390a1610d6e565b7f01d8973c54faac85b2cfd40f935f8da4261d9883283ad73ce0e10aa91fc37bdf60cc548260200151604051610d659291909182526001600160a01b0316602082015260400190565b60405180910390a15b505050505050565b6000828152609760205260408120610d8e9083611327565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610dea7f96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c33610d95565b610e455760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f756768207065726d697373696f6e7320746f2073657420636f6044820152651b9cdd185b9d60d21b606482015260840161056b565b600082604051602001610e589190611c34565b60405160208183030381529060405280519060200120905060cc548103610eb35760405162461bcd60e51b815260206004820152600f60248201526e24b731b7b93932b1ba1031b430b4b760891b604482015260640161056b565b6040517254696d654c696d69745065724d65737361676560681b602082015260330160408051808303601f190181528282528051602091820120600085815260d28352839020548452908301859052917fd9f6bd2abae0f2a51b3f5ffb29e0e35ee9ad2e3921ede0d71bff21dc8609f6f1910160405180910390a2600090815260d2602052604090205550565b600081815260976020526040812061048690611333565b600082815260656020526040902060010154610f72816111f2565b6104fa8383611221565b600054610100900460ff1615808015610f9c5750600054600160ff909116105b80610fb65750303b158015610fb6575060005460ff166001145b6110195760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161056b565b6000805460ff19166001179055801561103c576000805461ff0019166101001790555b6001600160a01b0382166110925760405162461bcd60e51b815260206004820152601a60248201527f4e6f646520616464726573732068617320746f20626520736574000000000000604482015260640161056b565b61109a61133d565b6110a56000336113aa565b60c980546001600160a01b038087166001600160a01b03199283161790925560ca8054928616929091169190911790556040516110e6908690602001611c34565b60408051601f19818403018152828252805160209182012060cc558282018252600783526613585a5b9b995d60ca1b83820152905161012c9260d292600092611130929101611c34565b60408051808303601f190181529181528151602092830120835290820192909252016000205560cb80546001600160a01b0319166001600160a01b03841617905580156108e1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006001600160e01b03198216637965db0b60e01b148061048657506301ffc9a760e01b6001600160e01b0319831614610486565b6111fc81336113b4565b50565b6112098282611418565b60008281526097602052604090206104fa908261149e565b61122b82826114b3565b60008281526097602052604090206104fa908261151a565b60008061125283850185611861565b905061125f602082611cba565b6000036112825761127a61127584838188611cdc565b611243565b915050610486565b61127a83850185611d1a565b604080516080810182526000606082018181528252602082018190529181019190915260076112bd8484611243565b600e8111156112ce576112ce611ca4565b1461131b5760405162461bcd60e51b815260206004820152601f60248201527f4d6573736167652074797065206973206e6f7420557365722053746174757300604482015260640161056b565b610d8e82840184611d35565b6000610d8e838361152f565b6000610486825490565b600054610100900460ff166113a85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161056b565b565b61057e82826111ff565b6113be8282610d95565b61057e576113d6816001600160a01b03166014611559565b6113e1836020611559565b6040516020016113f2929190611ddf565b60408051601f198184030181529082905262461bcd60e51b825261056b916004016118e3565b6114228282610d95565b61057e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561145a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610d8e836001600160a01b0384166116f5565b6114bd8282610d95565b1561057e5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610d8e836001600160a01b038416611744565b600082600001828154811061154657611546611e54565b9060005260206000200154905092915050565b60606000611568836002611e6a565b611573906002611c66565b67ffffffffffffffff81111561158b5761158b611916565b6040519080825280601f01601f1916602001820160405280156115b5576020820181803683370190505b509050600360fc1b816000815181106115d0576115d0611e54565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106115ff576115ff611e54565b60200101906001600160f81b031916908160001a9053506000611623846002611e6a565b61162e906001611c66565b90505b60018111156116a6576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061166257611662611e54565b1a60f81b82828151811061167857611678611e54565b60200101906001600160f81b031916908160001a90535060049490941c9361169f81611e89565b9050611631565b508315610d8e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161056b565b600081815260018301602052604081205461173c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610486565b506000610486565b6000818152600183016020526040812054801561182d576000611768600183611ea0565b855490915060009061177c90600190611ea0565b90508181146117e157600086600001828154811061179c5761179c611e54565b90600052602060002001549050808760000184815481106117bf576117bf611e54565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806117f2576117f2611eb3565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610486565b6000915050610486565b60006020828403121561184957600080fd5b81356001600160e01b031981168114610d8e57600080fd5b60006020828403121561187357600080fd5b5035919050565b6001600160a01b03811681146111fc57600080fd5b600080604083850312156118a257600080fd5b8235915060208301356118b48161187a565b809150509250929050565b60005b838110156118da5781810151838201526020016118c2565b50506000910152565b60208152600082518060208401526119028160408501602087016118bf565b601f01601f19169190910160400192915050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561194f5761194f611916565b60405290565b6040805190810167ffffffffffffffff8111828210171561194f5761194f611916565b600080600083850360e081121561198e57600080fd5b84359350602080860135935060a0603f19830112156119ac57600080fd5b6119b461192c565b915086605f8701126119c557600080fd5b6119cd611955565b8060808801898111156119df57600080fd5b604089015b818110156119fb57803584529284019284016119e4565b5090845235918301919091525060a0850135604082015260c0909401356060850152509093909250565b60008060008060608587031215611a3b57600080fd5b843593506020850135611a4d8161187a565b9250604085013567ffffffffffffffff80821115611a6a57600080fd5b818701915087601f830112611a7e57600080fd5b813581811115611a8d57600080fd5b886020828501011115611a9f57600080fd5b95989497505060200194505050565b60008060408385031215611ac157600080fd5b50508035926020909101359150565b600082601f830112611ae157600080fd5b813567ffffffffffffffff80821115611afc57611afc611916565b604051601f8301601f19908116603f01168101908282118183101715611b2457611b24611916565b81604052838152866020858801011115611b3d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215611b7057600080fd5b823567ffffffffffffffff811115611b8757600080fd5b611b9385828601611ad0565b95602094909401359450505050565b600060208284031215611bb457600080fd5b8135610d8e8161187a565b60008060008060808587031215611bd557600080fd5b843567ffffffffffffffff811115611bec57600080fd5b611bf887828801611ad0565b9450506020850135611c098161187a565b92506040850135611c198161187a565b91506060850135611c298161187a565b939692955090935050565b60008251611c468184602087016118bf565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561048657610486611c50565b80151581146111fc57600080fd5b600060208284031215611c9957600080fd5b8151610d8e81611c79565b634e487b7160e01b600052602160045260246000fd5b600082611cd757634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115611cec57600080fd5b83861115611cf957600080fd5b5050820193919092039150565b8035600f8110611d1557600080fd5b919050565b600060208284031215611d2c57600080fd5b610d8e82611d06565b60008183036060811215611d4857600080fd5b6040516060810167ffffffffffffffff8282108183111715611d6c57611d6c611916565b816040526020841215611d7e57600080fd5b6080830193508184108185111715611d9857611d98611916565b5082604052611da685611d06565b8152815260208401359150611dba8261187a565b81602082015260408401359150611dd082611c79565b60408101919091529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611e178160178501602088016118bf565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611e488160288401602088016118bf565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615611e8457611e84611c50565b500290565b600081611e9857611e98611c50565b506000190190565b8181038181111561048657610486611c50565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ffc2ba8b3668b63157574c2cfb07fd5725d38150fb0554a17a997986fd16016364736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xD2aaA007d2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806370a08231116100f9578063a9059cbb11610097578063d539139311610071578063d5391393146103b3578063d547741f146103da578063dd62ed3e146103ed578063e2d6f6341461040057600080fd5b8063a9059cbb1461037a578063c4d66de81461038d578063ca15c873146103a057600080fd5b806391d14854116100d357806391d148541461034457806395d89b4114610357578063a217fddf1461035f578063a457c2d71461036757600080fd5b806370a08231146102dd57806379cc6790146103065780639010d07c1461031957600080fd5b8063282c51f31161016657806336568abe1161014057806336568abe1461029157806339509351146102a457806340c10f19146102b757806342966c68146102ca57600080fd5b8063282c51f3146102465780632f2ff15d1461026d578063313ce5671461028257600080fd5b806301ffc9a7146101ae57806306fdde03146101d6578063095ea7b3146101eb57806318160ddd146101fe57806323b872dd14610210578063248a9ca314610223575b600080fd5b6101c16101bc36600461155c565b610413565b60405190151581526020015b60405180910390f35b6101de61043e565b6040516101cd91906115aa565b6101c16101f93660046115f9565b6104d0565b60cb545b6040519081526020016101cd565b6101c161021e366004611623565b6104e8565b61020261023136600461165f565b60009081526065602052604090206001015490565b6102027f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61028061027b366004611678565b61050c565b005b604051601281526020016101cd565b61028061029f366004611678565b610536565b6101c16102b23660046115f9565b6105b9565b6102806102c53660046115f9565b6105db565b6102806102d836600461165f565b61065b565b6102026102eb3660046116a4565b6001600160a01b0316600090815260c9602052604090205490565b6102806103143660046115f9565b610668565b61032c6103273660046116bf565b61067d565b6040516001600160a01b0390911681526020016101cd565b6101c1610352366004611678565b61069c565b6101de6106c7565b610202600081565b6101c16103753660046115f9565b6106d6565b6101c16103883660046115f9565b610751565b61028061039b3660046116a4565b61075f565b6102026103ae36600461165f565b610926565b6102027f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6102806103e8366004611678565b61093d565b6102026103fb3660046116e1565b610962565b61028061040e3660046115f9565b61098d565b60006001600160e01b03198216635a05180f60e01b1480610438575061043882610a03565b92915050565b606060cc805461044d9061170b565b80601f01602080910402602001604051908101604052809291908181526020018280546104799061170b565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b5050505050905090565b6000336104de818585610a38565b5060019392505050565b6000336104f6858285610b5c565b610501858585610bd6565b506001949350505050565b60008281526065602052604090206001015461052781610da4565b6105318383610dae565b505050565b6001600160a01b03811633146105ab5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105b58282610dd0565b5050565b6000336104de8185856105cc8383610962565b6105d6919061175b565b610a38565b6106057f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63361069c565b6106515760405162461bcd60e51b815260206004820152601760248201527f4d494e54455220726f6c6520697320726571756972656400000000000000000060448201526064016105a2565b6105b58282610df2565b6106653382610ed1565b50565b610673823383610b5c565b6105b58282610ed1565b6000828152609760205260408120610695908361101f565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd805461044d9061170b565b600033816106e48286610962565b9050838110156107445760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016105a2565b6105018286868403610a38565b6000336104de818585610bd6565b600054610100900460ff161580801561077f5750600054600160ff909116105b806107995750303b158015610799575060005460ff166001145b6107fc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105a2565b6000805460ff19166001179055801561081f576000805461ff0019166101001790555b61082761102b565b61087660405180604001604052806011815260200170455243323020457468657220436c6f6e6560781b815250604051806040016040528060048152602001634554484360e01b815250611054565b61087e61102b565b610889600033611085565b6108b37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a683611085565b6108dd7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84883611085565b80156105b5576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60008181526097602052604081206104389061108f565b60008281526065602052604090206001015461095881610da4565b6105318383610dd0565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6109b77f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483361069c565b6106735760405162461bcd60e51b815260206004820152601760248201527f4255524e455220726f6c6520697320726571756972656400000000000000000060448201526064016105a2565b60006001600160e01b03198216637965db0b60e01b148061043857506301ffc9a760e01b6001600160e01b0319831614610438565b6001600160a01b038316610a9a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016105a2565b6001600160a01b038216610afb5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016105a2565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000610b688484610962565b90506000198114610bd05781811015610bc35760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105a2565b610bd08484848403610a38565b50505050565b6001600160a01b038316610c3a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016105a2565b6001600160a01b038216610c9c5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016105a2565b6001600160a01b038316600090815260c9602052604090205481811015610d145760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016105a2565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610d4b90849061175b565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d9791815260200190565b60405180910390a3610bd0565b6106658133611099565b610db882826110fd565b60008281526097602052604090206105319082611183565b610dda8282611198565b600082815260976020526040902061053190826111ff565b6001600160a01b038216610e485760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105a2565b8060cb6000828254610e5a919061175b565b90915550506001600160a01b038216600090815260c9602052604081208054839290610e8790849061175b565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610f315760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016105a2565b6001600160a01b038216600090815260c9602052604090205481811015610fa55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016105a2565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610fd490849061176e565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006106958383611214565b600054610100900460ff166110525760405162461bcd60e51b81526004016105a290611781565b565b600054610100900460ff1661107b5760405162461bcd60e51b81526004016105a290611781565b6105b5828261123e565b6105b58282610dae565b6000610438825490565b6110a3828261069c565b6105b5576110bb816001600160a01b0316601461127e565b6110c683602061127e565b6040516020016110d79291906117cc565b60408051601f198184030181529082905262461bcd60e51b82526105a2916004016115aa565b611107828261069c565b6105b55760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561113f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610695836001600160a01b03841661141a565b6111a2828261069c565b156105b55760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610695836001600160a01b038416611469565b600082600001828154811061122b5761122b611841565b9060005260206000200154905092915050565b600054610100900460ff166112655760405162461bcd60e51b81526004016105a290611781565b60cc61127183826118bb565b5060cd61053182826118bb565b6060600061128d83600261197b565b61129890600261175b565b67ffffffffffffffff8111156112b0576112b0611857565b6040519080825280601f01601f1916602001820160405280156112da576020820181803683370190505b509050600360fc1b816000815181106112f5576112f5611841565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061132457611324611841565b60200101906001600160f81b031916908160001a905350600061134884600261197b565b61135390600161175b565b90505b60018111156113cb576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061138757611387611841565b1a60f81b82828151811061139d5761139d611841565b60200101906001600160f81b031916908160001a90535060049490941c936113c48161199a565b9050611356565b5083156106955760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016105a2565b600081815260018301602052604081205461146157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610438565b506000610438565b6000818152600183016020526040812054801561155257600061148d60018361176e565b85549091506000906114a19060019061176e565b90508181146115065760008660000182815481106114c1576114c1611841565b90600052602060002001549050808760000184815481106114e4576114e4611841565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611517576115176119b1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610438565b6000915050610438565b60006020828403121561156e57600080fd5b81356001600160e01b03198116811461069557600080fd5b60005b838110156115a1578181015183820152602001611589565b50506000910152565b60208152600082518060208401526115c9816040850160208701611586565b601f01601f19169190910160400192915050565b80356001600160a01b03811681146115f457600080fd5b919050565b6000806040838503121561160c57600080fd5b611615836115dd565b946020939093013593505050565b60008060006060848603121561163857600080fd5b611641846115dd565b925061164f602085016115dd565b9150604084013590509250925092565b60006020828403121561167157600080fd5b5035919050565b6000806040838503121561168b57600080fd5b8235915061169b602084016115dd565b90509250929050565b6000602082840312156116b657600080fd5b610695826115dd565b600080604083850312156116d257600080fd5b50508035926020909101359150565b600080604083850312156116f457600080fd5b6116fd836115dd565b915061169b602084016115dd565b600181811c9082168061171f57607f821691505b60208210810361173f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561043857610438611745565b8181038181111561043857610438611745565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611804816017850160208801611586565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611835816028840160208801611586565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f82111561053157600081815260208120601f850160051c810160208610156118945750805b601f850160051c820191505b818110156118b3578281556001016118a0565b505050505050565b815167ffffffffffffffff8111156118d5576118d5611857565b6118e9816118e3845461170b565b8461186d565b602080601f83116001811461191e57600084156119065750858301515b600019600386901b1c1916600185901b1785556118b3565b600085815260208120601f198616915b8281101561194d5788860151825594840194600190910190840161192e565b508582101561196b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081600019048311821515161561199557611995611745565b500290565b6000816119a9576119a9611745565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212204a8c446125b4466580bc5f64979dc7a7facca59521b4d0ebea6ecd938f789eda64736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xD2aaA00900000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x023e53b1d9fc4e87c67ca049b99030449c5fbc30fe2ba2dfd40c8ebf2b707219": "0x01", + "0x0c94570da19dff961fa301fdf83b467d2e96da7a41ee6dcc5c5f7ac33c270b8b": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x122f7d0619a5264c086c6547bffab20578c9fbf87522e041783d5d44beb2d25a": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa009d2000000000000000000000000000000", + "0x61d8ad11edb7edad4d8f3ba4ddc5c23ce790dfa64f07c35f257dc56cb7ce507b": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x6c8f1a70270c11627beb08e2afcc680f7fe60ee60ea538c3e5de154847fa0d8a": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0xab43ffaff5e7c8ac5804cdf58088ef28e1a2d3687a8068be710e369f38e47925": "0x01", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc9": "0xd2aaa00100000000000000000000000000000000", + "0xca": "0xd2aaa00800000000000000000000000000000000", + "0xcb": "0xd2aaa00300000000000000000000000000000000", + "0xcc": "0x5d625e25b9f1ef5d5b3778887e76df4fd02824a86b9d6138d7412f3305ac3813", + "0xcd": "0xd200000000000000000000000000000000000004", + "0xd65aeee08c5cda0d1c500775ee0d4d0a0db5bc751bbb2e734d1fda5833a58367": "0x01", + "0xff78f509c1fad38363f9cc13c767e3dece5b063d058a35423eb295bed984e41d": "0x01" + } + }, + "0xD2aaa00300000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa003d2000000000000000000000000000000", + "0x3b842995bb7793a90b453e7ee33bd2c16adcd3bfde40b84a935c55785cfad706": "0x012c", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc9": "0xd2aaa00100000000000000000000000000000000", + "0xca": "0xd2aaa00800000000000000000000000000000000", + "0xcb": "0xd200000000000000000000000000000000000006", + "0xcc": "0x5d625e25b9f1ef5d5b3778887e76df4fd02824a86b9d6138d7412f3305ac3813" + } + }, + "0xD2aaa00600000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x023e53b1d9fc4e87c67ca049b99030449c5fbc30fe2ba2dfd40c8ebf2b707219": "0x01", + "0x0c94570da19dff961fa301fdf83b467d2e96da7a41ee6dcc5c5f7ac33c270b8b": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x122f7d0619a5264c086c6547bffab20578c9fbf87522e041783d5d44beb2d25a": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa006d2000000000000000000000000000000", + "0x61d8ad11edb7edad4d8f3ba4ddc5c23ce790dfa64f07c35f257dc56cb7ce507b": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x6c8f1a70270c11627beb08e2afcc680f7fe60ee60ea538c3e5de154847fa0d8a": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0xab43ffaff5e7c8ac5804cdf58088ef28e1a2d3687a8068be710e369f38e47925": "0x01", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc9": "0xd2aaa00100000000000000000000000000000000", + "0xca": "0xd2aaa00800000000000000000000000000000000", + "0xcb": "0xd2aaa00300000000000000000000000000000000", + "0xcc": "0x5d625e25b9f1ef5d5b3778887e76df4fd02824a86b9d6138d7412f3305ac3813", + "0xcd": "0xd200000000000000000000000000000000000003", + "0xd65aeee08c5cda0d1c500775ee0d4d0a0db5bc751bbb2e734d1fda5833a58367": "0x01", + "0xff78f509c1fad38363f9cc13c767e3dece5b063d058a35423eb295bed984e41d": "0x01" + } + }, + "0xd2001DAb6898127Be2F167B548691C87251D13C3": { + "balance": "1000000000000000000" + }, + "0xd2AAA00Ad2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040523480156200001157600080fd5b5060043610620002495760003560e01c80636d611286116200013d578063b9581c5011620000bb578063cb703bff1162000086578063cb703bff14620005a6578063cc5b715b14620005bd578063d547741f14620005e5578063dec2deb614620005fc578063edcc12b5146200061157600080fd5b8063b9581c501462000537578063c0e312dc1462000541578063ca15c8731462000558578063ca99be02146200056f57600080fd5b80639010d07c11620001085780639010d07c14620004ae57806391d1485414620004c5578063a217fddf14620004dc578063aebaaca914620004e5578063b4a0522b146200050b57600080fd5b80636d61128614620004585780636d6c68e6146200046c5780636e81ae281462000480578063884cee5a146200049757600080fd5b80632f2ff15d11620001cb5780633fa194ce11620001965780633fa194ce14620003c957806350f4428014620003e05780635573b8b61462000416578063680ae2fe146200042a5780636ce681d2146200044157600080fd5b80632f2ff15d146200037a57806336568abe146200039157806339927cf914620003a85780633b690b6b14620003bf57600080fd5b80630f1a8f7411620002185780630f1a8f7414620002da5780631e0594e3146200031f578063248a9ca3146200033657806328c5e182146200035c5780632dc151de146200036657600080fd5b806301ffc9a7146200024e578063029996b8146200027a5780630b6c672314620002865780630b885ac314620002c3575b600080fd5b620002656200025f36600462003020565b62000628565b60405190151581526020015b60405180910390f35b6200028462000656565b005b620002b46200029736600462003062565b60d260209081526000928352604080842090915290825290205481565b60405190815260200162000271565b62000284620002d4366004620031d5565b620006ae565b62000306620002eb3660046200326a565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200162000271565b6200028462000330366004620032cf565b620006c4565b620002b4620003473660046200326a565b60009081526065602052604090206001015490565b620002b462000955565b60ca5462000306906001600160a01b031681565b620002846200038b36600462003331565b620009a0565b62000284620003a236600462003331565b620009ce565b62000265620003b936600462003364565b62000a50565b620002b460cc5481565b620002b46000805160206200666583398151915281565b620004076040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002719190620033fd565b60c95462000306906001600160a01b031681565b620002846200043b36600462003412565b62000aad565b6200028462000452366004620031d5565b62000dc6565b60cd5462000306906001600160a01b031681565b60cb5462000306906001600160a01b031681565b620002846200049136600462003062565b6200103a565b62000284620004a836600462003481565b6200114e565b62000306620004bf366004620034e2565b620012bb565b62000265620004d636600462003331565b620012dc565b620002b4600081565b62000265620004f636600462003505565b60d06020526000908152604090205460ff1681565b620003066200051c36600462003505565b60cf602052600090815260409020546001600160a01b031681565b6200028462001307565b620002846200055236600462003364565b62001350565b620002b4620005693660046200326a565b6200146e565b620003066200058036600462003331565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b62000284620005b736600462003525565b62001487565b620002b47ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000284620005f636600462003331565b6200160e565b60cd546200026590600160a01b900460ff1681565b620002846200062236600462003505565b62001637565b60006001600160e01b03198216635a05180f60e01b1480620006505750620006508262001753565b92915050565b620006716000805160206200666583398151915233620012dc565b620006995760405162461bcd60e51b8152600401620006909062003581565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006bd858585858562000dc6565b5050505050565b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040513394509092506200071091508490602001620035c2565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000752929101620035c2565b604051602081830303815290604052805190602001208103620007d15760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606482015260840162000690565b6001600160a01b038216620008295760405162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656365697665722061646472657373000000000000604482015260640162000690565b600081815260ce60205260409020546001600160a01b03166200088f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b60008787604051602001620008a6929190620035e0565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b1580156200090a57600080fd5b505af11580156200091f573d6000803e3d6000fd5b505050600082815260ce60205260409020546200094b915082906001600160a01b03168833896200178a565b5050505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009879190620035c2565b6040516020818303038152906040528051906020012081565b600082815260656020526040902060010154620009bd8162001be2565b620009c9838362001bf1565b505050565b6001600160a01b038116331462000a405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840162000690565b62000a4c828262001c17565b5050565b6000806001600160a01b031660ce6000858560405160200162000a75929190620035e0565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b62000ad97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012dc565b62000b275760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604482015260640162000690565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9062000b5b9087908790600401620035f0565b602060405180830381865afa15801562000b79573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b9f91906200361f565b62000be65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b604482015260640162000690565b6001600160a01b0381163b62000c3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b6000848460405160200162000c56929190620035e0565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b03888116835294529190912054909250161562000cda5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b604482015260640162000690565b6001600160a01b038216600090815260d0602052604090205460ff161562000d455760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c7265616479206164646564000000000000000000604482015260640162000690565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c91a45050505050565b600054610100900460ff161580801562000de75750600054600160ff909116105b8062000e035750303b15801562000e03575060005460ff166001145b62000e685760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000690565b6000805460ff19166001179055801562000e8c576000805461ff0019166101001790555b6001600160a01b03821662000ee45760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b62000eee62001c3d565b62000efb60003362001cac565b62000f16600080516020620066658339815191523362001cac565b62000f427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001cac565b8560405160200162000f559190620035c2565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562001032576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200107f929101620035c2565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620010d257600080fd5b505af1158015620010e7573d6000803e3d6000fd5b5050505062000a4c6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620011219190620035c2565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168433856200178a565b60c9546001600160a01b03163314620011aa5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604482015260640162000690565b838360cc548214158015620011c65750620011c6828262001cb8565b620012145760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f72726563740000000000604482015260640162000690565b600062001222858562001d43565b90506000600e82600e8111156200123d576200123d62003643565b14806200125e5750600d82600e8111156200125c576200125c62003643565b145b1562001279576200127188878762001d9a565b90506200094b565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604482015260640162000690565b6000828152609760205260408120620012d5908362002378565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b620013226000805160206200666583398151915233620012dc565b620013415760405162461bcd60e51b8152600401620006909062003581565b60cd805460ff60a01b19169055565b60ca546001600160a01b031633148062001372575062001372600033620012dc565b620013b85760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b60008282604051602001620013cf929190620035e0565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b03166200144e5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604482015260640162000690565b600090815260ce6020526040902080546001600160a01b03191690555050565b6000818152609760205260408120620006509062002386565b60ca546001600160a01b0316331480620014a95750620014a9600033620012dc565b620014ef5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b6000838360405160200162001506929190620035e0565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620015865760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604482015260640162000690565b6001600160a01b038216620015de5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b6000828152606560205260409020600101546200162b8162001be2565b620009c9838362001c17565b62001644600033620012dc565b620016925760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604482015260640162000690565b6001600160a01b038116620016ea5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200065057506301ffc9a760e01b6001600160e01b031983161462000650565b600085815260d1602090815260408083206001600160a01b038088168552925282205416806200182757506001600160a01b038416600090815260d06020526040902054849060ff1615620018225760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b600191505b6001600160a01b0381163b620018805760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604482015260640162000690565b60405163020604bf60e21b81526004810184905230906001600160a01b0383169063081812fc90602401602060405180830381865afa158015620018c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018ee919062003659565b6001600160a01b031614620019465760405162461bcd60e51b815260206004820152601860248201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604482015260640162000690565b6000620019618686866200195b868962002391565b62002404565b9050821562001aa9576040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200199c9190620035c2565b60405160208183030381529060405280519060200120880362001a1e5760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606482015260840162000690565b62001a2c8883338762002477565b905062001a3b8883866200252b565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001a8a57600080fd5b505af115801562001a9f573d6000803e3d6000fd5b5050505062001b6e565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001af857600080fd5b505af115801562001b0d573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018790526001600160a01b03851692506342966c689150602401600060405180830381600087803b15801562001b5457600080fd5b505af115801562001b69573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001ba4908b908b90869060040162003679565b600060405180830381600087803b15801562001bbf57600080fd5b505af115801562001bd4573d6000803e3d6000fd5b505050505050505050505050565b62001bee8133620025d3565b50565b62001bfd828262002642565b6000828152609760205260409020620009c99082620026cc565b62001c238282620026e3565b6000828152609760205260409020620009c990826200274d565b600054610100900460ff1662001caa5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000690565b565b62000a4c828262001bf1565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001cec9190620035c2565b60405160208183030381529060405280519060200120831462001d2c57600083815260ce60205260409020546001600160a01b03838116911614620012d5565b5060cd546001600160a01b03908116911614919050565b60008062001d54838501856200326a565b905062001d63602082620036ae565b60000362001d8c5762001d8362001d7d84838188620036d1565b62001d43565b91505062000650565b62001d838385018562003712565b60008062001da9848462001d43565b905060008080606081600d86600e81111562001dc95762001dc962003643565b0362001e5a57600062001ddd8a8a62002764565b90508060000151604001519550806000015160200151945080600001516060015193508060200151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031691505062002029565b600062001e688a8a6200282f565b9050806000015160000151604001519550806000015160000151602001519450806000015160000151606001519350806000015160200151925060d160008c81526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b031603620020275760cd54600160a01b900460ff1662001f645760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604482015260640162000690565b602080820151805191015160405162001f7d9062002fa9565b62001f8a92919062003730565b604051809103906000f08015801562001fa7573d6000803e3d6000fd5b5060008c815260d1602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918e917f3db9e29b45c5fe72aaa0bdc4514d68a645660185a44637e9bc6f0b805ea770459190a45b505b600d86600e81111562002040576200204062003643565b1480156200209557506040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200207b9190620035c2565b604051602081830303815290604052805190602001208a14155b8015620020a95750620020a98a85620028d4565b156200223f576001600160a01b0384163b620021085760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b6040516331a9108f60e11b81526004810184905230906001600160a01b03861690636352211e90602401602060405180830381865afa15801562002150573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002176919062003659565b6001600160a01b031614620021c25760405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081d1bdad95b9259607a1b604482015260640162000690565b620021cf8a85856200290b565b6040516323b872dd60e01b81523060048201526001600160a01b038681166024830152604482018590528516906323b872dd90606401600060405180830381600087803b1580156200222057600080fd5b505af115801562002235573d6000803e3d6000fd5b505050506200231b565b6040516340c10f1960e01b81526001600160a01b038681166004830152602482018590528216906340c10f1990604401600060405180830381600087803b1580156200228a57600080fd5b505af11580156200229f573d6000803e3d6000fd5b5050604051630588253160e21b81526001600160a01b038416925063162094c49150620022d3908690869060040162003759565b6020604051808303816000875af1158015620022f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200231991906200361f565b505b806001600160a01b0316846001600160a01b03168b7f2735a548eee1cda16c2df4c1a546c0376f3b3bb2ceca4966ef9d251fcbdd3c45866040516200236291815260200190565b60405180910390a4509298975050505050505050565b6000620012d58383620029b9565b600062000650825490565b60405163c87b56dd60e01b8152600481018290526060906001600160a01b0384169063c87b56dd90602401600060405180830381865afa158015620023da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620012d591908101906200377c565b6040805160e081018252600d60c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a083018690529082526020808301859052925190926200245d9183910162003863565b604051602081830303815290604052915050949350505050565b60606000620024878686620028d4565b905080620024c7576200249b8686620029e6565b620024bf858585620024ae898862002391565b620024b98a62002b1c565b62002c1a565b9150620024dd565b620024da8585856200195b898862002391565b91505b846001600160a01b0316867fd0fe87fb12c7aa2b7f679256044123cb20de43059fb2ddbb4cc6556f217f29dc856040516200251a91815260200190565b60405180910390a350949350505050565b6001600160a01b038216600090815260d26020908152604080832084845290915290205415620025ad5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420746f6044820152651031b430b4b760d11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290522055565b620025df8282620012dc565b62000a4c57620025fa816001600160a01b0316601462002c9a565b6200260783602062002c9a565b6040516020016200261a92919062003878565b60408051601f198184030181529082905262461bcd60e51b82526200069091600401620033fd565b6200264e8282620012dc565b62000a4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620026883390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012d5836001600160a01b03841662002e53565b620026ef8282620012dc565b1562000a4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012d5836001600160a01b03841662002ea5565b620027a46040805160e081018252600060c08201818152928201928352606082018190526080820181905260a08201529081908152602001606081525090565b600d620027b2848462001d43565b600e811115620027c657620027c662003643565b14620028215760405162461bcd60e51b815260206004820152602360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736044820152623332b960e91b606482015260840162000690565b620012d582840184620039c7565b6200283962002fb7565b600e62002847848462001d43565b600e8111156200285b576200285b62003643565b14620028c65760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604482015272666572207769746820746f6b656e20696e666f60681b606482015260840162000690565b620012d582840184620039ff565b600082815260d360205260408120620012d590836001600160a01b03811660009081526001830160205260408120541515620012d5565b6001600160a01b038216600090815260d2602090815260408083208484529091529020548314620029905760405162461bcd60e51b815260206004820152602860248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420667260448201526737b69031b430b4b760c11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290529081205550565b6000826000018281548110620029d357620029d362003af8565b9060005260206000200154905092915050565b6001600160a01b0381163b62002a3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b600082815260d36020526040902062002a7690826001600160a01b03811660009081526001830160205260408120541515620012d5565b1562002ac55760405162461bcd60e51b815260206004820152601e60248201527f45524337323120546f6b656e2077617320616c72656164792061646465640000604482015260640162000690565b600082815260d36020526040902062002adf9082620026cc565b506040516000906001600160a01b0383169084907f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c908490a45050565b60408051808201909152606080825260208201526040518060400160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002b7a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002ba491908101906200377c565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002be8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c1291908101906200377c565b905292915050565b6040805161012081018252600e6101008201908152608082019081526001600160a01b0380891660a0840152871660c083015260e08201869052818301908152606080830186905290825260208083018590529251909262002c7f9183910162003b0e565b60405160208183030381529060405291505095945050505050565b6060600062002cab83600262003b91565b62002cb890600262003bb3565b6001600160401b0381111562002cd25762002cd262003091565b6040519080825280601f01601f19166020018201604052801562002cfd576020820181803683370190505b509050600360fc1b8160008151811062002d1b5762002d1b62003af8565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002d4d5762002d4d62003af8565b60200101906001600160f81b031916908160001a905350600062002d7384600262003b91565b62002d8090600162003bb3565b90505b600181111562002e02576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002db85762002db862003af8565b1a60f81b82828151811062002dd15762002dd162003af8565b60200101906001600160f81b031916908160001a90535060049490941c9362002dfa8162003bc9565b905062002d83565b508315620012d55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000690565b600081815260018301602052604081205462002e9c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000650565b50600062000650565b6000818152600183016020526040812054801562002f9e57600062002ecc60018362003be3565b855490915060009062002ee29060019062003be3565b905081811462002f4e57600086600001828154811062002f065762002f0662003af8565b906000526020600020015490508087600001848154811062002f2c5762002f2c62003af8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002f625762002f6262003bf9565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000650565b600091505062000650565b612a558062003c1083390190565b6040805161012081018252600061010082018181526080830190815260a0830182905260c0830182905260e083019190915291810191825260608082015290819081526020016200301b604051806040016040528060608152602001606081525090565b905290565b6000602082840312156200303357600080fd5b81356001600160e01b031981168114620012d557600080fd5b6001600160a01b038116811462001bee57600080fd5b600080604083850312156200307657600080fd5b823562003083816200304c565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620030cc57620030cc62003091565b60405290565b604051608081016001600160401b0381118282101715620030cc57620030cc62003091565b604051602081016001600160401b0381118282101715620030cc57620030cc62003091565b604051601f8201601f191681016001600160401b038111828210171562003147576200314762003091565b604052919050565b60006001600160401b038211156200316b576200316b62003091565b50601f01601f191660200190565b600082601f8301126200318b57600080fd5b8135620031a26200319c826200314f565b6200311c565b818152846020838601011115620031b857600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215620031ee57600080fd5b85356001600160401b038111156200320557600080fd5b620032138882890162003179565b955050602086013562003226816200304c565b9350604086013562003238816200304c565b925060608601356200324a816200304c565b915060808601356200325c816200304c565b809150509295509295909350565b6000602082840312156200327d57600080fd5b5035919050565b60008083601f8401126200329757600080fd5b5081356001600160401b03811115620032af57600080fd5b602083019150836020828501011115620032c857600080fd5b9250929050565b60008060008060608587031215620032e657600080fd5b84356001600160401b03811115620032fd57600080fd5b6200330b8782880162003284565b909550935050602085013562003321816200304c565b9396929550929360400135925050565b600080604083850312156200334557600080fd5b82359150602083013562003359816200304c565b809150509250929050565b600080602083850312156200337857600080fd5b82356001600160401b038111156200338f57600080fd5b6200339d8582860162003284565b90969095509350505050565b60005b83811015620033c6578181015183820152602001620033ac565b50506000910152565b60008151808452620033e9816020860160208601620033a9565b601f01601f19169290920160200192915050565b602081526000620012d56020830184620033cf565b600080600080606085870312156200342957600080fd5b84356001600160401b038111156200344057600080fd5b6200344e8782880162003284565b909550935050602085013562003464816200304c565b9150604085013562003476816200304c565b939692955090935050565b600080600080606085870312156200349857600080fd5b843593506020850135620034ac816200304c565b925060408501356001600160401b03811115620034c857600080fd5b620034d68782880162003284565b95989497509550505050565b60008060408385031215620034f657600080fd5b50508035926020909101359150565b6000602082840312156200351857600080fd5b8135620012d5816200304c565b6000806000604084860312156200353b57600080fd5b83356001600160401b038111156200355257600080fd5b620035608682870162003284565b909450925050602084013562003576816200304c565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251620035d6818460208701620033a9565b9190910192915050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156200363257600080fd5b81518015158114620012d557600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156200366c57600080fd5b8151620012d5816200304c565b8381526001600160a01b0383166020820152606060408201819052600090620036a590830184620033cf565b95945050505050565b600082620036cc57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115620036e257600080fd5b83861115620036f057600080fd5b5050820193919092039150565b8035600f81106200370d57600080fd5b919050565b6000602082840312156200372557600080fd5b620012d582620036fd565b604081526000620037456040830185620033cf565b8281036020840152620036a58185620033cf565b828152604060208201526000620037746040830184620033cf565b949350505050565b6000602082840312156200378f57600080fd5b81516001600160401b03811115620037a657600080fd5b8201601f81018413620037b857600080fd5b8051620037c96200319c826200314f565b818152856020838501011115620037df57600080fd5b620036a5826020830160208601620033a9565b60008151805151600f81106200381857634e487b7160e01b600052602160045260246000fd5b84526020818101516001600160a01b0390811682870152604080840151909116908601526060918201519185019190915282015160a0608085018190526200377490850182620033cf565b602081526000620012d56020830184620037f2565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620038b2816017850160208801620033a9565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351620038e5816028840160208801620033a9565b01602801949350505050565b600081830360a08112156200390557600080fd5b6200390f620030a7565b915060808112156200392057600080fd5b6200392a620030d2565b60208212156200393957600080fd5b62003943620030f7565b91506200395084620036fd565b825290815260208301359062003966826200304c565b816020820152604084013591506200397e826200304c565b81604082015260608401356060820152808352505060808201356001600160401b03811115620039ad57600080fd5b620039bb8482850162003179565b60208301525092915050565b600060208284031215620039da57600080fd5b81356001600160401b03811115620039f157600080fd5b6200377484828501620038f1565b60006020828403121562003a1257600080fd5b81356001600160401b038082111562003a2a57600080fd5b908301906040828603121562003a3f57600080fd5b62003a49620030a7565b82358281111562003a5957600080fd5b62003a6787828601620038f1565b82525060208301358281111562003a7d57600080fd5b92909201916040838703121562003a9357600080fd5b62003a9d620030a7565b83358381111562003aad57600080fd5b62003abb8882870162003179565b82525060208401358381111562003ad157600080fd5b62003adf8882870162003179565b6020830152508060208301525080935050505092915050565b634e487b7160e01b600052603260045260246000fd5b60208152600082516040602084015262003b2c6060840182620037f2565b90506020840151601f1984830301604085015280516040835262003b546040840182620033cf565b905060208201519150828103602084015262003b718183620033cf565b9695505050505050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161562003bae5762003bae62003b7b565b500290565b8082018082111562000650576200065062003b7b565b60008162003bdb5762003bdb62003b7b565b506000190190565b8181038181111562000650576200065062003b7b565b634e487b7160e01b600052603160045260246000fdfe60806040523480156200001157600080fd5b5060405162002a5538038062002a558339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b62000a3c1760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b62000a4b1760201c565b6200013e83836200024660201b62000a741760201c565b62000153620001e860201b62000a4b1760201c565b6200016e60008051602062002a3583398151915280620002b2565b6200018960008051602062002a3583398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60c962000373838262000698565b5060ca62000382828262000698565b505050565b6200039e8282620003c560201b62000aa51760201c565b60008281526097602090815260409091206200038291839062000b2b62000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6122a180620007746000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220f4b1a553d0216fad85e7fc3c0111d94167f74f5dbb1455424ba58f7cf0009cba64736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xd2AAa00100000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x0796286937b3bd8c4482b89f40ecff37f0a38aa42be6365a35fd104759a54529": "0x05", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x19388c8ccd5bfcf1f050c8e1404d14cbca02a4779291c6b8431085b66a41c0b0": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa001d2000000000000000000000000000000", + "0x366a6cad7c27c88339589047396a2dd2f6b89f0efe82d8521b1d677f31e2ee72": "0x03", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x715a3a61a52d717d84dcf54d1ecf1177652c80cea3d15106ba5e65a48e9a1420": "0xd2aaa00400000000000000000000000000000000", + "0x715a3a61a52d717d84dcf54d1ecf1177652c80cea3d15106ba5e65a48e9a1421": "0xd2aaa00500000000000000000000000000000000", + "0x715a3a61a52d717d84dcf54d1ecf1177652c80cea3d15106ba5e65a48e9a1422": "0xd2aaa00600000000000000000000000000000000", + "0x715a3a61a52d717d84dcf54d1ecf1177652c80cea3d15106ba5e65a48e9a1423": "0xd2aaa00900000000000000000000000000000000", + "0x715a3a61a52d717d84dcf54d1ecf1177652c80cea3d15106ba5e65a48e9a1424": "0xd2aaa00a00000000000000000000000000000000", + "0x715a3a61a52d717d84dcf54d1ecf1177652c80cea3d15106ba5e65a48e9a1425": "0xd2aaa00300000000000000000000000000000000", + "0x7f065e1e45f30000fed336f6677c7a20bcff4fc4216506fbdda09100aa402c04": "0x01", + "0x9266783f1ae11c7e45269865e693dbe0406bcecaf294e8837abc7933b860f6b9": "0x06", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xcb": "0x2dc6c0", + "0xcc": "0xd2aaa00200000000000000000000000000000000", + "0xcd": "0x5d625e25b9f1ef5d5b3778887e76df4fd02824a86b9d6138d7412f3305ac3813", + "0xd2": "0x312e332e34613132000000000000000000000000000000000000000000000010", + "0xd5709b3c30eaa9520476e9b02bcf15803186dfe324e2c30aaa427e7a855eb8ad": "0x01", + "0xd64bc233e931cdee2f89673acd91ee8def4f3b3460f46eebee2d54988278dc42": "0xd2aaa00800000000000000000000000000000000", + "0xdd832eb5a073b0a5d7da8e7721df6463eec60e13252a725cba8d928ed468b12c": "0x04", + "0xe645a2c71e5ce0ce242fbf8fa5b08acfcf5d87b503c10d81ef370028290a21bb": "0x01", + "0xf17189186d89ebe17d4a2d0bf477b737e7c3930d88b5880d4a0c683d3b8339e9": "0x02", + "0xfa5413e7b01fc543d01f0911de573ace463b956369df4472f39030e8d98b77": "0x06", + "0xfdcb579ba011421f0dfae7ec536c5fb608270565d2517ed5cdd8a33bda07d604": "0x01" + } + }, + "0xd2AAa006d2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040523480156200001157600080fd5b5060043610620002495760003560e01c80636d611286116200013d578063b9581c5011620000bb578063cb703bff1162000086578063cb703bff14620005a6578063cc5b715b14620005bd578063d547741f14620005e5578063dec2deb614620005fc578063edcc12b5146200061157600080fd5b8063b9581c501462000537578063c0e312dc1462000541578063ca15c8731462000558578063ca99be02146200056f57600080fd5b80639010d07c11620001085780639010d07c14620004ae57806391d1485414620004c5578063a217fddf14620004dc578063aebaaca914620004e5578063b4a0522b146200050b57600080fd5b80636d61128614620004585780636d6c68e6146200046c5780636e81ae281462000480578063884cee5a146200049757600080fd5b80632f2ff15d11620001cb5780633fa194ce11620001965780633fa194ce14620003c957806350f4428014620003e05780635573b8b61462000416578063680ae2fe146200042a5780636ce681d2146200044157600080fd5b80632f2ff15d146200037a57806336568abe146200039157806339927cf914620003a85780633b690b6b14620003bf57600080fd5b80630f1a8f7411620002185780630f1a8f7414620002da5780631e0594e3146200031f578063248a9ca3146200033657806328c5e182146200035c5780632dc151de146200036657600080fd5b806301ffc9a7146200024e578063029996b8146200027a5780630b6c672314620002865780630b885ac314620002c3575b600080fd5b620002656200025f36600462002e6b565b62000628565b60405190151581526020015b60405180910390f35b6200028462000656565b005b620002b46200029736600462002ead565b60d260209081526000928352604080842090915290825290205481565b60405190815260200162000271565b62000284620002d436600462002fd6565b620006ae565b62000306620002eb3660046200306b565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200162000271565b6200028462000330366004620030d0565b620006c4565b620002b4620003473660046200306b565b60009081526065602052604090206001015490565b620002b462000955565b60ca5462000306906001600160a01b031681565b620002846200038b36600462003132565b620009a0565b62000284620003a236600462003132565b620009ce565b62000265620003b936600462003165565b62000a50565b620002b460cc5481565b620002b4600080516020620063d083398151915281565b620004076040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051620002719190620031fe565b60c95462000306906001600160a01b031681565b620002846200043b36600462003213565b62000aad565b620002846200045236600462002fd6565b62000dc6565b60cd5462000306906001600160a01b031681565b60cb5462000306906001600160a01b031681565b620002846200049136600462002ead565b6200103a565b62000284620004a836600462003282565b6200114e565b62000306620004bf366004620032e3565b620012bb565b62000265620004d636600462003132565b620012dc565b620002b4600081565b62000265620004f636600462003306565b60d06020526000908152604090205460ff1681565b620003066200051c36600462003306565b60cf602052600090815260409020546001600160a01b031681565b6200028462001307565b620002846200055236600462003165565b62001350565b620002b4620005693660046200306b565b6200146e565b620003066200058036600462003132565b60d16020908152600092835260408084209091529082529020546001600160a01b031681565b62000284620005b736600462003326565b62001487565b620002b47ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000284620005f636600462003132565b6200160e565b60cd546200026590600160a01b900460ff1681565b620002846200062236600462003306565b62001637565b60006001600160e01b03198216635a05180f60e01b1480620006505750620006508262001753565b92915050565b62000671600080516020620063d083398151915233620012dc565b620006995760405162461bcd60e51b8152600401620006909062003382565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006bd858585858562000dc6565b5050505050565b83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040513394509092506200071091508490602001620033c3565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000752929101620033c3565b604051602081830303815290604052805190602001208103620007d15760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b606482015260840162000690565b6001600160a01b038216620008295760405162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656365697665722061646472657373000000000000604482015260640162000690565b600081815260ce60205260409020546001600160a01b03166200088f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b60008787604051602001620008a6929190620033e1565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b1580156200090a57600080fd5b505af11580156200091f573d6000803e3d6000fd5b505050600082815260ce60205260409020546200094b915082906001600160a01b03168833896200178a565b5050505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620009879190620033c3565b6040516020818303038152906040528051906020012081565b600082815260656020526040902060010154620009bd8162001bd6565b620009c9838362001be5565b505050565b6001600160a01b038116331462000a405760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840162000690565b62000a4c828262001c0b565b5050565b6000806001600160a01b031660ce6000858560405160200162000a75929190620033e1565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b62000ad97ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba833620012dc565b62000b275760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c45206973207265717569726564604482015260640162000690565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9062000b5b9087908790600401620033f1565b602060405180830381865afa15801562000b79573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b9f919062003420565b62000be65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b604482015260640162000690565b6001600160a01b0381163b62000c3f5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b6000848460405160200162000c56929190620033e1565b60408051601f198184030181529181528151602092830120600081815260d184528281206001600160a01b03888116835294529190912054909250161562000cda5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b604482015260640162000690565b6001600160a01b038216600090815260d0602052604090205460ff161562000d455760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c7265616479206164646564000000000000000000604482015260640162000690565b600081815260d1602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d0909352818420805460ff1916600117905590519192909184917f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c91a45050505050565b600054610100900460ff161580801562000de75750600054600160ff909116105b8062000e035750303b15801562000e03575060005460ff166001145b62000e685760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000690565b6000805460ff19166001179055801562000e8c576000805461ff0019166101001790555b6001600160a01b03821662000ee45760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b62000eee62001c31565b62000efb60003362001ca0565b62000f16600080516020620063d08339815191523362001ca0565b62000f427ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001ca0565b8560405160200162000f559190620033c3565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562001032576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200107f929101620033c3565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620010d257600080fd5b505af1158015620010e7573d6000803e3d6000fd5b5050505062000a4c6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620011219190620033c3565b60408051601f19818403018152919052805160209091012060cd546001600160a01b03168433856200178a565b60c9546001600160a01b03163314620011aa5760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f787900000000604482015260640162000690565b838360cc548214158015620011c65750620011c6828262001cac565b620012145760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f72726563740000000000604482015260640162000690565b600062001222858562001d37565b90506000600682600e8111156200123d576200123d62003444565b14806200125e5750600582600e8111156200125c576200125c62003444565b145b1562001279576200127188878762001d8e565b90506200094b565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b604482015260640162000690565b6000828152609760205260408120620012d59083620022b2565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b62001322600080516020620063d083398151915233620012dc565b620013415760405162461bcd60e51b8152600401620006909062003382565b60cd805460ff60a01b19169055565b60ca546001600160a01b031633148062001372575062001372600033620012dc565b620013b85760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b60008282604051602001620013cf929190620033e1565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b03166200144e5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f74207365740000000000000000604482015260640162000690565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206200065090620022c0565b60ca546001600160a01b0316331480620014a95750620014a9600033620012dc565b620014ef5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604482015260640162000690565b6000838360405160200162001506929190620033e1565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620015865760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c72656164792073657400000000604482015260640162000690565b6001600160a01b038216620015de5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e61676572206164647265737300604482015260640162000690565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b6000828152606560205260409020600101546200162b8162001bd6565b620009c9838362001c0b565b62001644600033620012dc565b620016925760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c452069732072657175697265640000604482015260640162000690565b6001600160a01b038116620016ea5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f20626520736574604482015260640162000690565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200065057506301ffc9a760e01b6001600160e01b031983161462000650565b600085815260d1602090815260408083206001600160a01b038088168552925282205416806200182757506001600160a01b038416600090815260d06020526040902054849060ff1615620018225760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b600191505b6001600160a01b0381163b620018805760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e0000000000000000604482015260640162000690565b60405163020604bf60e21b81526004810184905230906001600160a01b0383169063081812fc90602401602060405180830381865afa158015620018c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018ee91906200345a565b6001600160a01b031614620019465760405162461bcd60e51b815260206004820152601860248201527f4e6f7420616c6c6f7765642045524337323120546f6b656e0000000000000000604482015260640162000690565b600062001955868686620022cb565b9050821562001a9d576040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001620019909190620033c3565b60405160208183030381529060405280519060200120880362001a125760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b606482015260840162000690565b62001a20888333876200232c565b905062001a2f888386620023dc565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001a7e57600080fd5b505af115801562001a93573d6000803e3d6000fd5b5050505062001b62565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401600060405180830381600087803b15801562001aec57600080fd5b505af115801562001b01573d6000803e3d6000fd5b5050604051630852cd8d60e31b8152600481018790526001600160a01b03851692506342966c689150602401600060405180830381600087803b15801562001b4857600080fd5b505af115801562001b5d573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001b98908b908b9086906004016200347a565b600060405180830381600087803b15801562001bb357600080fd5b505af115801562001bc8573d6000803e3d6000fd5b505050505050505050505050565b62001be2813362002484565b50565b62001bf18282620024f3565b6000828152609760205260409020620009c990826200257d565b62001c17828262002594565b6000828152609760205260409020620009c99082620025fe565b600054610100900460ff1662001c9e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000690565b565b62000a4c828262001be5565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001ce09190620033c3565b60405160208183030381529060405280519060200120831462001d2057600083815260ce60205260409020546001600160a01b03838116911614620012d5565b5060cd546001600160a01b03908116911614919050565b60008062001d48838501856200306b565b905062001d57602082620034af565b60000362001d805762001d7762001d7184838188620034d2565b62001d37565b91505062000650565b62001d778385018562003513565b60008062001d9d848462001d37565b90506000808080600585600e81111562001dbb5762001dbb62003444565b0362001e1557600062001dcf898962002615565b60408082015160208084015160609094015160008f815260d183528481206001600160a01b0380881683529352939093205491985092965090945016915062001fcd9050565b600062001e238989620026ca565b905080600001516040015194508060000151602001519350806000015160600151925060d160008b81526020019081526020016000206000856001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b0316915060006001600160a01b0316826001600160a01b03160362001fcb5760cd54600160a01b900460ff1662001f085760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c656400000000604482015260640162000690565b602080820151805191015160405162001f219062002e06565b62001f2e92919062003531565b604051809103906000f08015801562001f4b573d6000803e3d6000fd5b5060008b815260d1602090815260408083206001600160a01b0389811680865291845282852080546001600160a01b031916918716918217905580855260d0909352818420805460ff191660011790559051939550909290918d917f3db9e29b45c5fe72aaa0bdc4514d68a645660185a44637e9bc6f0b805ea770459190a45b505b600585600e81111562001fe45762001fe462003444565b1480156200203957506040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016200201f9190620033c3565b604051602081830303815290604052805190602001208914155b80156200205b5750600089815260d3602052604090206200205b90846200276f565b15620021f1576001600160a01b0383163b620020ba5760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e000000000000604482015260640162000690565b6040516331a9108f60e11b81526004810183905230906001600160a01b03851690636352211e90602401602060405180830381865afa15801562002102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200212891906200345a565b6001600160a01b031614620021745760405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081d1bdad95b9259607a1b604482015260640162000690565b6200218189848462002792565b6040516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490528416906323b872dd90606401600060405180830381600087803b158015620021d257600080fd5b505af1158015620021e7573d6000803e3d6000fd5b5050505062002256565b6040516340c10f1960e01b81526001600160a01b038581166004830152602482018490528216906340c10f1990604401600060405180830381600087803b1580156200223c57600080fd5b505af115801562002251573d6000803e3d6000fd5b505050505b806001600160a01b0316836001600160a01b03168a7f2735a548eee1cda16c2df4c1a546c0376f3b3bb2ceca4966ef9d251fcbdd3c45856040516200229d91815260200190565b60405180910390a45091979650505050505050565b6000620012d5838362002840565b600062000650825490565b6040805160a08101825260056080820190815281526001600160a01b0380861660208084019190915290851682840152606080830185905292516200231391839101620035ae565b6040516020818303038152906040529150509392505050565b600084815260d360205260408120606091906200234a90866200276f565b9050806200237e576200235e86866200286d565b62002376858585620023708962002986565b62002a84565b91506200238e565b6200238b858585620022cb565b91505b846001600160a01b0316867fd0fe87fb12c7aa2b7f679256044123cb20de43059fb2ddbb4cc6556f217f29dc85604051620023cb91815260200190565b60405180910390a350949350505050565b6001600160a01b038216600090815260d260209081526040808320848452909152902054156200245e5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420746f6044820152651031b430b4b760d11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290522055565b620024908282620012dc565b62000a4c57620024ab816001600160a01b0316601462002af7565b620024b883602062002af7565b604051602001620024cb929190620035be565b60408051601f198184030181529082905262461bcd60e51b82526200069091600401620031fe565b620024ff8282620012dc565b62000a4c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620025393390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620012d5836001600160a01b03841662002cb0565b620025a08282620012dc565b1562000a4c5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000620012d5836001600160a01b03841662002d02565b6040805160a081018252600060808201818152825260208201819052918101829052606081019190915260056200264d848462001d37565b600e81111562002661576200266162003444565b14620026bc5760405162461bcd60e51b815260206004820152602360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e736044820152623332b960e91b606482015260840162000690565b620012d582840184620036fa565b620026d462002e14565b6006620026e2848462001d37565b600e811115620026f657620026f662003444565b14620027615760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f7420455243373231207472616e73604482015272666572207769746820746f6b656e20696e666f60681b606482015260840162000690565b620012d58284018462003719565b6001600160a01b03811660009081526001830160205260408120541515620012d5565b6001600160a01b038216600090815260d2602090815260408083208484529091529020548314620028175760405162461bcd60e51b815260206004820152602860248201527f546f6b656e2077617320616c7265616479207472616e7366657272656420667260448201526737b69031b430b4b760c11b606482015260840162000690565b6001600160a01b03909116600090815260d2602090815260408083209383529290529081205550565b60008260000182815481106200285a576200285a620037ff565b9060005260206000200154905092915050565b6001600160a01b0381163b620028c65760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e747261637400604482015260640162000690565b600082815260d360205260409020620028e090826200276f565b156200292f5760405162461bcd60e51b815260206004820152601e60248201527f45524337323120546f6b656e2077617320616c72656164792061646465640000604482015260640162000690565b600082815260d3602052604090206200294990826200257d565b506040516000906001600160a01b0383169084907f11bec40858c3e219ac2d82dd307a6989e3ea72d1c463dfce7376c149d5ccf30c908490a45050565b60408051808201909152606080825260208201526040518060400160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015620029e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002a0e919081019062003815565b8152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002a52573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002a7c919081019062003815565b905292915050565b6040805160e081018252600660c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a0830186905290825260208083018590529251909262002add918391016200388b565b604051602081830303815290604052915050949350505050565b6060600062002b08836002620038fc565b62002b159060026200391e565b6001600160401b0381111562002b2f5762002b2f62002edc565b6040519080825280601f01601f19166020018201604052801562002b5a576020820181803683370190505b509050600360fc1b8160008151811062002b785762002b78620037ff565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002baa5762002baa620037ff565b60200101906001600160f81b031916908160001a905350600062002bd0846002620038fc565b62002bdd9060016200391e565b90505b600181111562002c5f576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002c155762002c15620037ff565b1a60f81b82828151811062002c2e5762002c2e620037ff565b60200101906001600160f81b031916908160001a90535060049490941c9362002c578162003934565b905062002be0565b508315620012d55760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000690565b600081815260018301602052604081205462002cf95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000650565b50600062000650565b6000818152600183016020526040812054801562002dfb57600062002d296001836200394e565b855490915060009062002d3f906001906200394e565b905081811462002dab57600086600001828154811062002d635762002d63620037ff565b906000526020600020015490508087600001848154811062002d895762002d89620037ff565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002dbf5762002dbf62003964565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000650565b600091505062000650565b612a55806200397b83390190565b6040805160e081018252600060c08201818152928201928352606082018190526080820181905260a0820152908190815260200162002e66604051806040016040528060608152602001606081525090565b905290565b60006020828403121562002e7e57600080fd5b81356001600160e01b031981168114620012d557600080fd5b6001600160a01b038116811462001be257600080fd5b6000806040838503121562002ec157600080fd5b823562002ece8162002e97565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171562002f175762002f1762002edc565b60405290565b604051601f8201601f191681016001600160401b038111828210171562002f485762002f4862002edc565b604052919050565b60006001600160401b0382111562002f6c5762002f6c62002edc565b50601f01601f191660200190565b600082601f83011262002f8c57600080fd5b813562002fa362002f9d8262002f50565b62002f1d565b81815284602083860101111562002fb957600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121562002fef57600080fd5b85356001600160401b038111156200300657600080fd5b620030148882890162002f7a565b9550506020860135620030278162002e97565b93506040860135620030398162002e97565b925060608601356200304b8162002e97565b915060808601356200305d8162002e97565b809150509295509295909350565b6000602082840312156200307e57600080fd5b5035919050565b60008083601f8401126200309857600080fd5b5081356001600160401b03811115620030b057600080fd5b602083019150836020828501011115620030c957600080fd5b9250929050565b60008060008060608587031215620030e757600080fd5b84356001600160401b03811115620030fe57600080fd5b6200310c8782880162003085565b9095509350506020850135620031228162002e97565b9396929550929360400135925050565b600080604083850312156200314657600080fd5b8235915060208301356200315a8162002e97565b809150509250929050565b600080602083850312156200317957600080fd5b82356001600160401b038111156200319057600080fd5b6200319e8582860162003085565b90969095509350505050565b60005b83811015620031c7578181015183820152602001620031ad565b50506000910152565b60008151808452620031ea816020860160208601620031aa565b601f01601f19169290920160200192915050565b602081526000620012d56020830184620031d0565b600080600080606085870312156200322a57600080fd5b84356001600160401b038111156200324157600080fd5b6200324f8782880162003085565b9095509350506020850135620032658162002e97565b91506040850135620032778162002e97565b939692955090935050565b600080600080606085870312156200329957600080fd5b843593506020850135620032ad8162002e97565b925060408501356001600160401b03811115620032c957600080fd5b620032d78782880162003085565b95989497509550505050565b60008060408385031215620032f757600080fd5b50508035926020909101359150565b6000602082840312156200331957600080fd5b8135620012d58162002e97565b6000806000604084860312156200333c57600080fd5b83356001600160401b038111156200335357600080fd5b620033618682870162003085565b9094509250506020840135620033778162002e97565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251620033d7818460208701620031aa565b9190910192915050565b8183823760009101908152919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156200343357600080fd5b81518015158114620012d557600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156200346d57600080fd5b8151620012d58162002e97565b8381526001600160a01b0383166020820152606060408201819052600090620034a690830184620031d0565b95945050505050565b600082620034cd57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115620034e357600080fd5b83861115620034f157600080fd5b5050820193919092039150565b8035600f81106200350e57600080fd5b919050565b6000602082840312156200352657600080fd5b620012d582620034fe565b604081526000620035466040830185620031d0565b8281036020840152620034a68185620031d0565b805151600f81106200357c57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b039081169184019190915260408083015190911690830152606090810151910152565b608081016200065082846200355a565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620035f8816017850160208801620031aa565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516200362b816028840160208801620031aa565b01602801949350505050565b600081830360808112156200364b57600080fd5b604051608081016001600160401b03828210818311171562003671576200367162002edc565b8160405282945060208412156200368757600080fd5b60a0830193508184108185111715620036a457620036a462002edc565b5082604052620036b485620034fe565b8152815260208401359150620036ca8262002e97565b81602082015260408401359150620036e28262002e97565b81604082015260608401356060820152505092915050565b6000608082840312156200370d57600080fd5b620012d5838362003637565b6000602082840312156200372c57600080fd5b81356001600160401b03808211156200374457600080fd5b9083019060a082860312156200375957600080fd5b6200376362002ef2565b6200376f868462003637565b81526080830135828111156200378457600080fd5b9290920191604083870312156200379a57600080fd5b620037a462002ef2565b833583811115620037b457600080fd5b620037c28882870162002f7a565b825250602084013583811115620037d857600080fd5b620037e68882870162002f7a565b6020830152508060208301525080935050505092915050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200382857600080fd5b81516001600160401b038111156200383f57600080fd5b8201601f810184136200385157600080fd5b80516200386262002f9d8262002f50565b8181528560208385010111156200387857600080fd5b620034a6826020830160208601620031aa565b602081526200389f6020820183516200355a565b6000602083015160a0808401528051604060c0850152620038c5610100850182620031d0565b90506020820151915060bf198482030160e0850152620034a68183620031d0565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620039195762003919620038e6565b500290565b80820180821115620006505762000650620038e6565b600081620039465762003946620038e6565b506000190190565b81810381811115620006505762000650620038e6565b634e487b7160e01b600052603160045260246000fdfe60806040523480156200001157600080fd5b5060405162002a5538038062002a558339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b62000a3c1760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b62000a4b1760201c565b6200013e83836200024660201b62000a741760201c565b62000153620001e860201b62000a4b1760201c565b6200016e60008051602062002a3583398151915280620002b2565b6200018960008051602062002a3583398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062002a1583398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60c962000373838262000698565b5060ca62000382828262000698565b505050565b6200039e8282620003c560201b62000aa51760201c565b60008281526097602090815260409091206200038291839062000b2b62000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6122a180620007746000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063a22cb46511610097578063ca15c87311610071578063ca15c87314610340578063d539139314610353578063d547741f1461037a578063e985e9c51461038d57600080fd5b8063a22cb46514610307578063b88d4fde1461031a578063c87b56dd1461032d57600080fd5b80636352211e146102ab57806370a08231146102be5780639010d07c146102d157806391d14854146102e457806395d89b41146102f7578063a217fddf146102ff57600080fd5b8063248a9ca311610130578063248a9ca31461021b5780632f2ff15d1461024c57806336568abe1461025f57806340c10f191461027257806342842e0e1461028557806342966c681461029857600080fd5b806301ffc9a71461017857806306fdde03146101a0578063081812fc146101b5578063095ea7b3146101e0578063162094c4146101f557806323b872dd14610208575b600080fd5b61018b610186366004611aed565b6103c9565b60405190151581526020015b60405180910390f35b6101a86103da565b6040516101979190611b5a565b6101c86101c3366004611b6d565b61046c565b6040516001600160a01b039091168152602001610197565b6101f36101ee366004611ba2565b610493565b005b61018b610203366004611bcc565b6105ad565b6101f3610216366004611c48565b6106d9565b61023e610229366004611b6d565b60009081526065602052604090206001015490565b604051908152602001610197565b6101f361025a366004611c84565b61070b565b6101f361026d366004611c84565b610730565b6101f3610280366004611ba2565b6107ae565b6101f3610293366004611c48565b610827565b6101f36102a6366004611b6d565b610842565b6101c86102b9366004611b6d565b610873565b61023e6102cc366004611cb0565b6108d3565b6101c86102df366004611ccb565b610959565b61018b6102f2366004611c84565b610978565b6101a86109a3565b61023e600081565b6101f3610315366004611ced565b6109b2565b6101f3610328366004611d3f565b6109bd565b6101a861033b366004611b6d565b6109f5565b61023e61034e366004611b6d565b610a00565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101f3610388366004611c84565b610a17565b61018b61039b366004611e1b565b6001600160a01b03918216600090815260ce6020908152604080832093909416825291909152205460ff1690565b60006103d482610b40565b92915050565b606060c980546103e990611e45565b80601f016020809104026020016040519081016040528092919081815260200182805461041590611e45565b80156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050905090565b600061047782610b80565b50600090815260cd60205260409020546001600160a01b031690565b600061049e82610873565b9050806001600160a01b0316836001600160a01b0316036105105760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061052c575061052c813361039b565b61059e5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610507565b6105a88383610bdf565b505050565b600083815260cb60205260408120546001600160a01b03166106095760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20646f6573206e6f742065786973747360581b6044820152606401610507565b6106133385610c4d565b8061064357506106437f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61068f5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722063616e206e6f742073657420746f6b656e20555249000000006044820152606401610507565b6106cf8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ccc92505050565b5060019392505050565b6106e4335b82610c4d565b6107005760405162461bcd60e51b815260040161050790611e7f565b6105a8838383610d60565b60008281526065602052604090206001015461072681610efc565b6105a88383610f06565b6001600160a01b03811633146107a05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610507565b6107aa8282610f28565b5050565b6107d87f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610978565b61081d5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610507565b6107aa8282610f4a565b6105a8838383604051806020016040528060008152506109bd565b61084b336106de565b6108675760405162461bcd60e51b815260040161050790611e7f565b6108708161108c565b50565b600081815260cb60205260408120546001600160a01b0316806103d45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b60006001600160a01b03821661093d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610507565b506001600160a01b0316600090815260cc602052604090205490565b60008281526097602052604081206109719083611095565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060ca80546103e990611e45565b6107aa3383836110a1565b6109c73383610c4d565b6109e35760405162461bcd60e51b815260040161050790611e7f565b6109ef8484848461116f565b50505050565b60606103d4826111a2565b60008181526097602052604081206103d4906112ab565b600082815260656020526040902060010154610a3281610efc565b6105a88383610f28565b6001600160a01b03163b151590565b600054610100900460ff16610a725760405162461bcd60e51b815260040161050790611ecd565b565b600054610100900460ff16610a9b5760405162461bcd60e51b815260040161050790611ecd565b6107aa82826112b5565b610aaf8282610978565b6107aa5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ae73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610971836001600160a01b0384166112f5565b60006001600160e01b031982166380ac58cd60e01b1480610b7157506001600160e01b03198216635b5e139f60e01b145b806103d457506103d482611344565b600081815260cb60205260409020546001600160a01b03166108705760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610507565b600081815260cd6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610c1482610873565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610c5983610873565b9050806001600160a01b0316846001600160a01b03161480610ca057506001600160a01b03808216600090815260ce602090815260408083209388168352929052205460ff165b80610cc45750836001600160a01b0316610cb98461046c565b6001600160a01b0316145b949350505050565b600082815260cb60205260409020546001600160a01b0316610d475760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610507565b600082815261012d602052604090206105a88282611f66565b826001600160a01b0316610d7382610873565b6001600160a01b031614610dd75760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610507565b6001600160a01b038216610e395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610507565b610e44600082610bdf565b6001600160a01b038316600090815260cc60205260408120805460019290610e6d90849061203c565b90915550506001600160a01b038216600090815260cc60205260408120805460019290610e9b90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6108708133611369565b610f108282610aa5565b60008281526097602052604090206105a89082610b2b565b610f3282826113cd565b60008281526097602052604090206105a89082611434565b6001600160a01b038216610fa05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610507565b600081815260cb60205260409020546001600160a01b0316156110055760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610507565b6001600160a01b038216600090815260cc6020526040812080546001929061102e90849061204f565b9091555050600081815260cb602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61087081611449565b6000610971838361148b565b816001600160a01b0316836001600160a01b0316036111025760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610507565b6001600160a01b03838116600081815260ce6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61117a848484610d60565b611186848484846114b5565b6109ef5760405162461bcd60e51b815260040161050790612062565b60606111ad82610b80565b600082815261012d6020526040812080546111c790611e45565b80601f01602080910402602001604051908101604052809291908181526020018280546111f390611e45565b80156112405780601f1061121557610100808354040283529160200191611240565b820191906000526020600020905b81548152906001019060200180831161122357829003601f168201915b50505050509050600061125e60408051602081019091526000815290565b90508051600003611270575092915050565b8151156112a257808260405160200161128a9291906120b4565b60405160208183030381529060405292505050919050565b610cc4846115b6565b60006103d4825490565b600054610100900460ff166112dc5760405162461bcd60e51b815260040161050790611ecd565b60c96112e88382611f66565b5060ca6105a88282611f66565b600081815260018301602052604081205461133c575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556103d4565b5060006103d4565b60006001600160e01b03198216635a05180f60e01b14806103d457506103d482611629565b6113738282610978565b6107aa5761138b816001600160a01b0316601461165e565b61139683602061165e565b6040516020016113a79291906120e3565b60408051601f198184030181529082905262461bcd60e51b825261050791600401611b5a565b6113d78282610978565b156107aa5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610971836001600160a01b0384166117fa565b611452816118ed565b600081815261012d60205260409020805461146c90611e45565b15905061087057600081815261012d6020526040812061087091611a89565b60008260000182815481106114a2576114a2612158565b9060005260206000200154905092915050565b60006001600160a01b0384163b156115ab57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906114f990339089908890889060040161216e565b6020604051808303816000875af1925050508015611534575060408051601f3d908101601f19168201909252611531918101906121ab565b60015b611591573d808015611562576040519150601f19603f3d011682016040523d82523d6000602084013e611567565b606091505b5080516000036115895760405162461bcd60e51b815260040161050790612062565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610cc4565b506001949350505050565b60606115c182610b80565b60006115d860408051602081019091526000815290565b905060008151116115f85760405180602001604052806000815250610971565b8061160284611988565b6040516020016116139291906120b4565b6040516020818303038152906040529392505050565b60006001600160e01b03198216637965db0b60e01b14806103d457506301ffc9a760e01b6001600160e01b03198316146103d4565b6060600061166d8360026121c8565b61167890600261204f565b67ffffffffffffffff81111561169057611690611d29565b6040519080825280601f01601f1916602001820160405280156116ba576020820181803683370190505b509050600360fc1b816000815181106116d5576116d5612158565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061170457611704612158565b60200101906001600160f81b031916908160001a90535060006117288460026121c8565b61173390600161204f565b90505b60018111156117ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061176757611767612158565b1a60f81b82828151811061177d5761177d612158565b60200101906001600160f81b031916908160001a90535060049490941c936117a4816121e7565b9050611736565b5083156109715760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610507565b600081815260018301602052604081205480156118e357600061181e60018361203c565b85549091506000906118329060019061203c565b905081811461189757600086600001828154811061185257611852612158565b906000526020600020015490508087600001848154811061187557611875612158565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a8576118a86121fe565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506103d4565b60009150506103d4565b60006118f882610873565b9050611905600083610bdf565b6001600160a01b038116600090815260cc6020526040812080546001929061192e90849061203c565b9091555050600082815260cb602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060816000036119af5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156119d957806119c381612214565b91506119d29050600a83612243565b91506119b3565b60008167ffffffffffffffff8111156119f4576119f4611d29565b6040519080825280601f01601f191660200182016040528015611a1e576020820181803683370190505b5090505b8415610cc457611a3360018361203c565b9150611a40600a86612257565b611a4b90603061204f565b60f81b818381518110611a6057611a60612158565b60200101906001600160f81b031916908160001a905350611a82600a86612243565b9450611a22565b508054611a9590611e45565b6000825580601f10611aa5575050565b601f01602090049060005260206000209081019061087091905b80821115611ad35760008155600101611abf565b5090565b6001600160e01b03198116811461087057600080fd5b600060208284031215611aff57600080fd5b813561097181611ad7565b60005b83811015611b25578181015183820152602001611b0d565b50506000910152565b60008151808452611b46816020860160208601611b0a565b601f01601f19169290920160200192915050565b6020815260006109716020830184611b2e565b600060208284031215611b7f57600080fd5b5035919050565b80356001600160a01b0381168114611b9d57600080fd5b919050565b60008060408385031215611bb557600080fd5b611bbe83611b86565b946020939093013593505050565b600080600060408486031215611be157600080fd5b83359250602084013567ffffffffffffffff80821115611c0057600080fd5b818601915086601f830112611c1457600080fd5b813581811115611c2357600080fd5b876020828501011115611c3557600080fd5b6020830194508093505050509250925092565b600080600060608486031215611c5d57600080fd5b611c6684611b86565b9250611c7460208501611b86565b9150604084013590509250925092565b60008060408385031215611c9757600080fd5b82359150611ca760208401611b86565b90509250929050565b600060208284031215611cc257600080fd5b61097182611b86565b60008060408385031215611cde57600080fd5b50508035926020909101359150565b60008060408385031215611d0057600080fd5b611d0983611b86565b915060208301358015158114611d1e57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215611d5557600080fd5b611d5e85611b86565b9350611d6c60208601611b86565b925060408501359150606085013567ffffffffffffffff80821115611d9057600080fd5b818701915087601f830112611da457600080fd5b813581811115611db657611db6611d29565b604051601f8201601f19908116603f01168101908382118183101715611dde57611dde611d29565b816040528281528a6020848701011115611df757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611e2e57600080fd5b611e3783611b86565b9150611ca760208401611b86565b600181811c90821680611e5957607f821691505b602082108103611e7957634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b601f8211156105a857600081815260208120601f850160051c81016020861015611f3f5750805b601f850160051c820191505b81811015611f5e57828155600101611f4b565b505050505050565b815167ffffffffffffffff811115611f8057611f80611d29565b611f9481611f8e8454611e45565b84611f18565b602080601f831160018114611fc95760008415611fb15750858301515b600019600386901b1c1916600185901b178555611f5e565b600085815260208120601f198616915b82811015611ff857888601518255948401946001909101908401611fd9565b50858210156120165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b818103818111156103d4576103d4612026565b808201808211156103d4576103d4612026565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b600083516120c6818460208801611b0a565b8351908301906120da818360208801611b0a565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161211b816017850160208801611b0a565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161214c816028840160208801611b0a565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121a190830184611b2e565b9695505050505050565b6000602082840312156121bd57600080fd5b815161097181611ad7565b60008160001904831182151516156121e2576121e2612026565b500290565b6000816121f6576121f6612026565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006001820161222657612226612026565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826122525761225261222d565b500490565b6000826122665761226661222d565b50069056fea2646970667358221220bb44f536146db5420851b152450b1223d86620092917329913619d017d6b2d0264736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220e9aba35f782fd339b68cf1550bc34c62e595e97e45bdf03ed99ec5022485429664736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xd2AaA00400000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x023e53b1d9fc4e87c67ca049b99030449c5fbc30fe2ba2dfd40c8ebf2b707219": "0x01", + "0x0c94570da19dff961fa301fdf83b467d2e96da7a41ee6dcc5c5f7ac33c270b8b": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x122f7d0619a5264c086c6547bffab20578c9fbf87522e041783d5d44beb2d25a": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa004d2000000000000000000000000000000", + "0x61d8ad11edb7edad4d8f3ba4ddc5c23ce790dfa64f07c35f257dc56cb7ce507b": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x6c8f1a70270c11627beb08e2afcc680f7fe60ee60ea538c3e5de154847fa0d8a": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0xab43ffaff5e7c8ac5804cdf58088ef28e1a2d3687a8068be710e369f38e47925": "0x01", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc9": "0xd2aaa00100000000000000000000000000000000", + "0xca": "0xd2aaa00800000000000000000000000000000000", + "0xcb": "0xd2aaa00300000000000000000000000000000000", + "0xcc": "0x5d625e25b9f1ef5d5b3778887e76df4fd02824a86b9d6138d7412f3305ac3813", + "0xcd": "0xd200000000000000000000000000000000000001", + "0xcf": "0xd2aaa00700000000000000000000000000000000", + "0xd65aeee08c5cda0d1c500775ee0d4d0a0db5bc751bbb2e734d1fda5833a58367": "0x01", + "0xff78f509c1fad38363f9cc13c767e3dece5b063d058a35423eb295bed984e41d": "0x01" + } + }, + "0xd2AaA004d2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80638182e7071161010f578063c0e312dc116100a2578063d547741f11610071578063d547741f1461046c578063dec2deb61461047f578063edcc12b514610493578063eeeb9601146104a657600080fd5b8063c0e312dc1461040c578063ca15c8731461041f578063cb703bff14610432578063cc5b715b1461044557600080fd5b806391d14854116100de57806391d14854146103d657806392d7846a146103e9578063a217fddf146103fc578063b9581c501461040457600080fd5b80638182e7071461038a578063884cee5a1461039d5780638b71b4b5146103b05780639010d07c146103c357600080fd5b806339927cf9116101875780635573b8b6116101565780635573b8b61461033e5780636ce681d2146103515780636d611286146103645780636d6c68e61461037757600080fd5b806339927cf9146102da5780633b690b6b146102ed5780633fa194ce146102f657806350f442801461030b57600080fd5b806328c5e182116101c357806328c5e182146102995780632dc151de146102a15780632f2ff15d146102b457806336568abe146102c757600080fd5b806301ffc9a7146101f5578063029996b81461021d5780630f1a8f7414610227578063248a9ca314610268575b600080fd5b610208610203366004611904565b6104b9565b60405190151581526020015b60405180910390f35b6102256104e4565b005b61025061023536600461192e565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610214565b61028b61027636600461192e565b60009081526065602052604090206001015490565b604051908152602001610214565b61028b610536565b60ca54610250906001600160a01b031681565b6102256102c236600461195c565b61057f565b6102256102d536600461195c565b6105a9565b6102086102e83660046119d5565b610627565b61028b60cc5481565b61028b6000805160206120e283398151915281565b6103316040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516102149190611a67565b60c954610250906001600160a01b031681565b61022561035f366004611b1d565b610682565b60cd54610250906001600160a01b031681565b60cb54610250906001600160a01b031681565b610225610398366004611ba7565b61089b565b6102256103ab366004611c42565b61098b565b6102256103be366004611c9e565b610b1e565b6102506103d1366004611cbb565b610bba565b6102086103e436600461195c565b610bd9565b60cf54610250906001600160a01b031681565b61028b600081565b610225610c04565b61022561041a3660046119d5565b610c47565b61028b61042d36600461192e565b610d34565b610225610440366004611cdd565b610d4b565b61028b7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b61022561047a36600461195c565b610e9f565b60cd5461020890600160a01b900460ff1681565b6102256104a1366004611c9e565b610ec4565b6102256104b436600461192e565b610fda565b60006001600160e01b03198216635a05180f60e01b14806104de57506104de826110e8565b92915050565b6104fc6000805160206120e283398151915233610bd9565b6105215760405162461bcd60e51b815260040161051890611d34565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b6040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016105669190611d75565b6040516020818303038152906040528051906020012081565b60008281526065602052604090206001015461059a8161111d565b6105a48383611127565b505050565b6001600160a01b03811633146106195760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610518565b6106238282611149565b5050565b6000806001600160a01b031660ce6000858560405160200161064a929190611d91565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b600054610100900460ff16158080156106a25750600054600160ff909116105b806106bc5750303b1580156106bc575060005460ff166001145b6106d85760405162461bcd60e51b815260040161051890611da1565b6000805460ff1916600117905580156106fb576000805461ff0019166101001790555b6001600160a01b0382166107515760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401610518565b61075961116b565b6107646000336111d8565b61077c6000805160206120e2833981519152336111d8565b6107a67ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba8336111d8565b856040516020016107b79190611d75565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a18015610893576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b600054610100900460ff16158080156108bb5750600054600160ff909116105b806108d55750303b1580156108d5575060005460ff166001145b6108f15760405162461bcd60e51b815260040161051890611da1565b6000805460ff191660011790558015610914576000805461ff0019166101001790555b6109218787878787610682565b60cf80546001600160a01b0319166001600160a01b0384161790558015610982576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60c9546001600160a01b031633146109e55760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f7879000000006044820152606401610518565b838360cc5482141580156109fe57506109fe82826111e2565b610a4a5760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f727265637400000000006044820152606401610518565b6000610a56858561124a565b60208101519091506001600160a01b038116610aa95760405162461bcd60e51b815260206004820152601260248201527124b731b7b93932b1ba103932b1b2b4bb32b960711b6044820152606401610518565b60cf5460408381015190516340c10f1960e01b81526001600160a01b03848116600483015260248201929092529116906340c10f1990604401600060405180830381600087803b158015610afc57600080fd5b505af1158015610b10573d6000803e3d6000fd5b505050505050505050505050565b610b29600033610bd9565b610b455760405162461bcd60e51b815260040161051890611def565b60cf546001600160a01b03808316911603610b985760405162461bcd60e51b81526020600482015260136024820152724d757374206265206e6577206164647265737360681b6044820152606401610518565b60cf80546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152609760205260408120610bd290836112e3565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610c1c6000805160206120e283398151915233610bd9565b610c385760405162461bcd60e51b815260040161051890611d34565b60cd805460ff60a01b19169055565b60ca546001600160a01b0316331480610c665750610c66600033610bd9565b610c825760405162461bcd60e51b815260040161051890611def565b60008282604051602001610c97929190611d91565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316610d145760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f742073657400000000000000006044820152606401610518565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206104de906112ef565b60ca546001600160a01b0316331480610d6a5750610d6a600033610bd9565b610d865760405162461bcd60e51b815260040161051890611def565b60008383604051602001610d9b929190611d91565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615610e195760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c726561647920736574000000006044820152606401610518565b6001600160a01b038216610e6f5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401610518565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b600082815260656020526040902060010154610eba8161111d565b6105a48383611149565b610ecf600033610bd9565b610f1b5760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401610518565b6001600160a01b038116610f715760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401610518565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b039093169263593157929261101d929101611d75565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b15801561106f57600080fd5b505af1158015611083573d6000803e3d6000fd5b505050506110e56040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016110ba9190611d75565b60408051601f19818403018152919052805160209091012060cd546001600160a01b031633846112f9565b50565b60006001600160e01b03198216637965db0b60e01b14806104de57506301ffc9a760e01b6001600160e01b03198316146104de565b6110e581336113de565b6111318282611442565b60008281526097602052604090206105a490826114c8565b61115382826114dd565b60008281526097602052604090206105a49082611544565b600054610100900460ff166111d65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610518565b565b6106238282611127565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b8152506040516020016112149190611d75565b6040516020818303038152906040528051906020012083148015610bd257505060cd546001600160a01b03908116911614919050565b604080516080810182526000606082018181528252602082018190529181019190915260016112798484611559565b600e81111561128a5761128a611e1e565b146112d75760405162461bcd60e51b815260206004820181905260248201527f4d6573736167652074797065206973206e6f7420455448207472616e736665726044820152606401610518565b610bd282840184611e48565b6000610bd283836115a4565b60006104de825490565b80156113645760cf546040516338b5bd8d60e21b8152336004820152602481018390526001600160a01b039091169063e2d6f63490604401600060405180830381600087803b15801561134b57600080fd5b505af115801561135f573d6000803e3d6000fd5b505050505b600061137083836115ce565b60c954604051634a24490160e11b81529192506001600160a01b0316906394489202906113a590889088908690600401611ee8565b600060405180830381600087803b1580156113bf57600080fd5b505af11580156113d3573d6000803e3d6000fd5b505050505050505050565b6113e88282610bd9565b61062357611400816001600160a01b03166014611626565b61140b836020611626565b60405160200161141c929190611f1b565b60408051601f198184030181529082905262461bcd60e51b825261051891600401611a67565b61144c8282610bd9565b6106235760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556114843390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610bd2836001600160a01b0384166117c2565b6114e78282610bd9565b156106235760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610bd2836001600160a01b038416611811565b6000806115688385018561192e565b9050611575602082611f90565b6000036115985761159061158b84838188611fb2565b611559565b9150506104de565b61159083850185611fdc565b60008260000182815481106115bb576115bb611ff7565b9060005260206000200154905092915050565b60408051608081018252600160608083019182529082526001600160a01b0385166020808401919091528284018590529251909261160e9183910161200d565b60405160208183030381529060405291505092915050565b6060600061163583600261206f565b61164090600261208e565b67ffffffffffffffff81111561165857611658611a7a565b6040519080825280601f01601f191660200182016040528015611682576020820181803683370190505b509050600360fc1b8160008151811061169d5761169d611ff7565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106116cc576116cc611ff7565b60200101906001600160f81b031916908160001a90535060006116f084600261206f565b6116fb90600161208e565b90505b6001811115611773576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061172f5761172f611ff7565b1a60f81b82828151811061174557611745611ff7565b60200101906001600160f81b031916908160001a90535060049490941c9361176c816120a1565b90506116fe565b508315610bd25760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610518565b6000818152600183016020526040812054611809575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104de565b5060006104de565b600081815260018301602052604081205480156118fa5760006118356001836120b8565b8554909150600090611849906001906120b8565b90508181146118ae57600086600001828154811061186957611869611ff7565b906000526020600020015490508087600001848154811061188c5761188c611ff7565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118bf576118bf6120cb565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104de565b60009150506104de565b60006020828403121561191657600080fd5b81356001600160e01b031981168114610bd257600080fd5b60006020828403121561194057600080fd5b5035919050565b6001600160a01b03811681146110e557600080fd5b6000806040838503121561196f57600080fd5b82359150602083013561198181611947565b809150509250929050565b60008083601f84011261199e57600080fd5b50813567ffffffffffffffff8111156119b657600080fd5b6020830191508360208285010111156119ce57600080fd5b9250929050565b600080602083850312156119e857600080fd5b823567ffffffffffffffff8111156119ff57600080fd5b611a0b8582860161198c565b90969095509350505050565b60005b83811015611a32578181015183820152602001611a1a565b50506000910152565b60008151808452611a53816020860160208601611a17565b601f01601f19169290920160200192915050565b602081526000610bd26020830184611a3b565b634e487b7160e01b600052604160045260246000fd5b600082601f830112611aa157600080fd5b813567ffffffffffffffff80821115611abc57611abc611a7a565b604051601f8301601f19908116603f01168101908282118183101715611ae457611ae4611a7a565b81604052838152866020858801011115611afd57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a08688031215611b3557600080fd5b853567ffffffffffffffff811115611b4c57600080fd5b611b5888828901611a90565b9550506020860135611b6981611947565b93506040860135611b7981611947565b92506060860135611b8981611947565b91506080860135611b9981611947565b809150509295509295909350565b60008060008060008060c08789031215611bc057600080fd5b863567ffffffffffffffff811115611bd757600080fd5b611be389828a01611a90565b9650506020870135611bf481611947565b94506040870135611c0481611947565b93506060870135611c1481611947565b92506080870135611c2481611947565b915060a0870135611c3481611947565b809150509295509295509295565b60008060008060608587031215611c5857600080fd5b843593506020850135611c6a81611947565b9250604085013567ffffffffffffffff811115611c8657600080fd5b611c928782880161198c565b95989497509550505050565b600060208284031215611cb057600080fd5b8135610bd281611947565b60008060408385031215611cce57600080fd5b50508035926020909101359150565b600080600060408486031215611cf257600080fd5b833567ffffffffffffffff811115611d0957600080fd5b611d158682870161198c565b9094509250506020840135611d2981611947565b809150509250925092565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b60008251611d87818460208701611a17565b9190910192915050565b8183823760009101908152919050565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601590820152742737ba1030baba3437b934bd32b21031b0b63632b960591b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b8035600f8110611e4357600080fd5b919050565b60008183036060811215611e5b57600080fd5b6040516060810167ffffffffffffffff8282108183111715611e7f57611e7f611a7a565b816040526020841215611e9157600080fd5b6080830193508184108185111715611eab57611eab611a7a565b5082604052611eb985611e34565b8152815260208401359150611ecd82611947565b81602082015260408401356040820152809250505092915050565b8381526001600160a01b0383166020820152606060408201819052600090611f1290830184611a3b565b95945050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611f53816017850160208801611a17565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611f84816028840160208801611a17565b01602801949350505050565b600082611fad57634e487b7160e01b600052601260045260246000fd5b500690565b60008085851115611fc257600080fd5b83861115611fcf57600080fd5b5050820193919092039150565b600060208284031215611fee57600080fd5b610bd282611e34565b634e487b7160e01b600052603260045260246000fd5b8151516060820190600f811061203357634e487b7160e01b600052602160045260246000fd5b82526020838101516001600160a01b031690830152604092830151929091019190915290565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561208957612089612059565b500290565b808201808211156104de576104de612059565b6000816120b0576120b0612059565b506000190190565b818103818111156104de576104de612059565b634e487b7160e01b600052603160045260246000fdfe7164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220ea530cdb7a3468cc605b8922313d6c065d2db0cde0a03bc2ff50f292214a3bb664736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xd2AaA00a00000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x023e53b1d9fc4e87c67ca049b99030449c5fbc30fe2ba2dfd40c8ebf2b707219": "0x01", + "0x0c94570da19dff961fa301fdf83b467d2e96da7a41ee6dcc5c5f7ac33c270b8b": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x122f7d0619a5264c086c6547bffab20578c9fbf87522e041783d5d44beb2d25a": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa00ad2000000000000000000000000000000", + "0x61d8ad11edb7edad4d8f3ba4ddc5c23ce790dfa64f07c35f257dc56cb7ce507b": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0x6c8f1a70270c11627beb08e2afcc680f7fe60ee60ea538c3e5de154847fa0d8a": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0xab43ffaff5e7c8ac5804cdf58088ef28e1a2d3687a8068be710e369f38e47925": "0x01", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000", + "0xc9": "0xd2aaa00100000000000000000000000000000000", + "0xca": "0xd2aaa00800000000000000000000000000000000", + "0xcb": "0xd2aaa00300000000000000000000000000000000", + "0xcc": "0x5d625e25b9f1ef5d5b3778887e76df4fd02824a86b9d6138d7412f3305ac3813", + "0xcd": "0xd200000000000000000000000000000000000007", + "0xd65aeee08c5cda0d1c500775ee0d4d0a0db5bc751bbb2e734d1fda5833a58367": "0x01", + "0xff78f509c1fad38363f9cc13c767e3dece5b063d058a35423eb295bed984e41d": "0x01" + } + }, + "0xd2aAA008D2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101425760003560e01c80635573b8b6116100b8578063a217fddf1161007c578063a217fddf146102d9578063b9727f96146102e1578063ca15c873146102f4578063d547741f14610307578063e953c9921461031a578063f68e95531461032d57600080fd5b80635573b8b61461027a57806364a5142f1461028d5780639010d07c146102a057806391d14854146102b3578063990c85e6146102c657600080fd5b8063291f60d31161010a578063291f60d3146101d05780632f2ff15d146101e357806336568abe146101f657806341ecadf914610209578063485cc9551461023457806350f442801461024757600080fd5b806301ffc9a714610147578063041f4c9b1461016f578063173df64b14610182578063248a9ca31461019757806328c5e182146101c8575b600080fd5b61015a6101553660046112b6565b610342565b60405190151581526020015b60405180910390f35b61015a61017d3660046112e0565b61036d565b6101956101903660046112e0565b6104ad565b005b6101ba6101a5366004611352565b60009081526065602052604090206001015490565b604051908152602001610166565b6101ba6105f5565b6101956101de366004611380565b61063e565b6101956101f136600461139d565b6106c4565b61019561020436600461139d565b6106ee565b61021c610217366004611352565b61076c565b6040516001600160a01b039091168152602001610166565b6101956102423660046113cd565b610796565b61026d6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b604051610166919061141f565b60c95461021c906001600160a01b031681565b60ca5461021c906001600160a01b031681565b61021c6102ae366004611452565b61095b565b61015a6102c136600461139d565b61097a565b6101956102d43660046112e0565b6109a5565b6101ba600081565b6101956102ef366004611380565b610b20565b6101ba610302366004611352565b610c76565b61019561031536600461139d565b610c8d565b61015a610328366004611380565b610cb2565b6101ba60008051602061169583398151915281565b60006001600160e01b03198216635a05180f60e01b1480610367575061036782610d20565b92915050565b60cb5460019060005b8181101561042957828015610415575060cb818154811061039957610399611474565b6000918252602090912001546040516339927cf960e01b81526001600160a01b03909116906339927cf9906103d490889088906004016114b3565b602060405180830381865afa1580156103f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061041591906114c7565b925080610421816114ff565b915050610376565b508180156104a5575060c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa9061046490879087906004016114b3565b602060405180830381865afa158015610481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a591906114c7565b949350505050565b6104c56000805160206116958339815191523361097a565b6104ea5760405162461bcd60e51b81526004016104e190611518565b60405180910390fd5b60cb5460005b8181101561058b5760cb818154811061050b5761050b611474565b600091825260209091200154604051633038c4b760e21b81526001600160a01b039091169063c0e312dc9061054690879087906004016114b3565b600060405180830381600087803b15801561056057600080fd5b505af1158015610574573d6000803e3d6000fd5b505050508080610583906114ff565b9150506104f0565b5060c954604051633cdd2cc360e01b81526001600160a01b0390911690633cdd2cc3906105be90869086906004016114b3565b600060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b50505050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b815250604051602001610625919061154f565b6040516020818303038152906040528051906020012081565b6106566000805160206116958339815191523361097a565b6106725760405162461bcd60e51b81526004016104e190611518565b60cb80546001810182556000919091527fa7ce836d032b2bf62b7e2097a8e0a6d8aeb35405ad15271e96d3b0188a1d06fb0180546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152606560205260409020600101546106df81610d55565b6106e98383610d62565b505050565b6001600160a01b038116331461075e5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016104e1565b6107688282610d84565b5050565b60cb818154811061077c57600080fd5b6000918252602090912001546001600160a01b0316905081565b600054610100900460ff16158080156107b65750600054600160ff909116105b806107d05750303b1580156107d0575060005460ff166001145b6108335760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016104e1565b6000805460ff191660011790558015610856576000805461ff0019166101001790555b6001600160a01b0382166108ac5760405162461bcd60e51b815260206004820152601c60248201527f4c696e6b657220616464726573732068617320746f206265207365740000000060448201526064016104e1565b6108b4610da6565b6108bf600033610e13565b6108d760008051602061169583398151915233610e13565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca80549285169290911691909117905560cc805460ff1916905580156106e9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60008281526097602052604081206109739083610e1d565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6109bd6000805160206116958339815191523361097a565b6109d95760405162461bcd60e51b81526004016104e190611518565b60005b60cb54811015610ab75760cb81815481106109f9576109f9611474565b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663cb703bff848460cb8581548110610a3a57610a3a611474565b6000918252602090912001546040516001600160e01b031960e086901b168152610a729392916001600160a01b03169060040161156b565b600060405180830381600087803b158015610a8c57600080fd5b505af1158015610aa0573d6000803e3d6000fd5b505050508080610aaf906114ff565b9150506109dc565b5060c95460405163f2f6360560e01b81526001600160a01b039091169063f2f6360590610aea90859085906004016114b3565b600060405180830381600087803b158015610b0457600080fd5b505af1158015610b18573d6000803e3d6000fd5b505050505050565b610b386000805160206116958339815191523361097a565b610b545760405162461bcd60e51b81526004016104e190611518565b60cb546000905b80821015610bac57826001600160a01b031660cb8381548110610b8057610b80611474565b6000918252602090912001546001600160a01b031614610bac5781610ba4816114ff565b925050610b5b565b808210156106e957610bbf600182611597565b821015610c3e5760cb610bd3600183611597565b81548110610be357610be3611474565b60009182526020909120015460cb80546001600160a01b039092169184908110610c0f57610c0f611474565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b60cb805480610c4f57610c4f6115aa565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b600081815260976020526040812061036790610e29565b600082815260656020526040902060010154610ca881610d55565b6106e98383610d84565b60cb5460009081905b80821015610d1657836001600160a01b031660cb8381548110610ce057610ce0611474565b6000918252602090912001546001600160a01b031603610d04575060019392505050565b81610d0e816114ff565b925050610cbb565b5060009392505050565b60006001600160e01b03198216637965db0b60e01b148061036757506301ffc9a760e01b6001600160e01b0319831614610367565b610d5f8133610e33565b50565b610d6c8282610e97565b60008281526097602052604090206106e99082610f1d565b610d8e8282610f32565b60008281526097602052604090206106e99082610f99565b600054610100900460ff16610e115760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104e1565b565b6107688282610d62565b60006109738383610fae565b6000610367825490565b610e3d828261097a565b61076857610e55816001600160a01b03166014610fd8565b610e60836020610fd8565b604051602001610e719291906115c0565b60408051601f198184030181529082905262461bcd60e51b82526104e19160040161141f565b610ea1828261097a565b6107685760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610ed93390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610973836001600160a01b038416611174565b610f3c828261097a565b156107685760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610973836001600160a01b0384166111c3565b6000826000018281548110610fc557610fc5611474565b9060005260206000200154905092915050565b60606000610fe7836002611635565b610ff2906002611654565b67ffffffffffffffff81111561100a5761100a611667565b6040519080825280601f01601f191660200182016040528015611034576020820181803683370190505b509050600360fc1b8160008151811061104f5761104f611474565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061107e5761107e611474565b60200101906001600160f81b031916908160001a90535060006110a2846002611635565b6110ad906001611654565b90505b6001811115611125576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110e1576110e1611474565b1a60f81b8282815181106110f7576110f7611474565b60200101906001600160f81b031916908160001a90535060049490941c9361111e8161167d565b90506110b0565b5083156109735760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016104e1565b60008181526001830160205260408120546111bb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610367565b506000610367565b600081815260018301602052604081205480156112ac5760006111e7600183611597565b85549091506000906111fb90600190611597565b905081811461126057600086600001828154811061121b5761121b611474565b906000526020600020015490508087600001848154811061123e5761123e611474565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611271576112716115aa565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610367565b6000915050610367565b6000602082840312156112c857600080fd5b81356001600160e01b03198116811461097357600080fd5b600080602083850312156112f357600080fd5b823567ffffffffffffffff8082111561130b57600080fd5b818501915085601f83011261131f57600080fd5b81358181111561132e57600080fd5b86602082850101111561134057600080fd5b60209290920196919550909350505050565b60006020828403121561136457600080fd5b5035919050565b6001600160a01b0381168114610d5f57600080fd5b60006020828403121561139257600080fd5b81356109738161136b565b600080604083850312156113b057600080fd5b8235915060208301356113c28161136b565b809150509250929050565b600080604083850312156113e057600080fd5b82356113eb8161136b565b915060208301356113c28161136b565b60005b838110156114165781810151838201526020016113fe565b50506000910152565b602081526000825180602084015261143e8160408501602087016113fb565b601f01601f19169190910160400192915050565b6000806040838503121561146557600080fd5b50508035926020909101359150565b634e487b7160e01b600052603260045260246000fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006104a560208301848661148a565b6000602082840312156114d957600080fd5b8151801515811461097357600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611511576115116114e9565b5060010190565b6020808252601a908201527f5245474953545241525f524f4c45206973207265717569726564000000000000604082015260600190565b600082516115618184602087016113fb565b9190910192915050565b60408152600061157f60408301858761148a565b905060018060a01b0383166020830152949350505050565b81810381811115610367576103676114e9565b634e487b7160e01b600052603160045260246000fd5b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516115f88160178501602088016113fb565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516116298160288401602088016113fb565b01602801949350505050565b600081600019048311821515161561164f5761164f6114e9565b500290565b80820180821115610367576103676114e9565b634e487b7160e01b600052604160045260246000fd5b60008161168c5761168c6114e9565b50600019019056feedcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c309238a26469706673582212205c3ac6ab85f1fd2aa105748f1966cb6a752e6f4f19ee82ab54ceea3706fb192a64736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xd2aAa00000000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461011157806399a88ec414610124578063f2fde38b14610144578063f3b7dead146101645761007b565b8063204e1c7a14610080578063715018a6146100bc5780637eff275e146100d35780638da5cb5b146100f3575b600080fd5b34801561008c57600080fd5b506100a061009b3660046104d8565b610184565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c857600080fd5b506100d1610215565b005b3480156100df57600080fd5b506100d16100ee366004610517565b610254565b3480156100ff57600080fd5b506000546001600160a01b03166100a0565b6100d161011f36600461054f565b6102de565b34801561013057600080fd5b506100d161013f366004610517565b61036f565b34801561015057600080fd5b506100d161015f3660046104d8565b6103c7565b34801561017057600080fd5b506100a061017f3660046104d8565b610462565b6000806000836001600160a01b03166040516101aa90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d80600081146101e5576040519150601f19603f3d011682016040523d82523d6000602084013e6101ea565b606091505b5091509150816101f957600080fd5b8080602001905181019061020d91906104fb565b949350505050565b6000546001600160a01b031633146102485760405162461bcd60e51b815260040161023f90610683565b60405180910390fd5b6102526000610488565b565b6000546001600160a01b0316331461027e5760405162461bcd60e51b815260040161023f90610683565b6040516308f2839760e41b81526001600160a01b038281166004830152831690638f283970906024015b600060405180830381600087803b1580156102c257600080fd5b505af11580156102d6573d6000803e3d6000fd5b505050505050565b6000546001600160a01b031633146103085760405162461bcd60e51b815260040161023f90610683565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906103389086908690600401610620565b6000604051808303818588803b15801561035157600080fd5b505af1158015610365573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b031633146103995760405162461bcd60e51b815260040161023f90610683565b604051631b2ce7f360e11b81526001600160a01b038281166004830152831690633659cfe6906024016102a8565b6000546001600160a01b031633146103f15760405162461bcd60e51b815260040161023f90610683565b6001600160a01b0381166104565760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161023f565b61045f81610488565b50565b6000806000836001600160a01b03166040516101aa906303e1469160e61b815260040190565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156104e9578081fd5b81356104f4816106ce565b9392505050565b60006020828403121561050c578081fd5b81516104f4816106ce565b60008060408385031215610529578081fd5b8235610534816106ce565b91506020830135610544816106ce565b809150509250929050565b600080600060608486031215610563578081fd5b833561056e816106ce565b9250602084013561057e816106ce565b9150604084013567ffffffffffffffff8082111561059a578283fd5b818601915086601f8301126105ad578283fd5b8135818111156105bf576105bf6106b8565b604051601f8201601f19908116603f011681019083821181831017156105e7576105e76106b8565b816040528281528960208487010111156105ff578586fd5b82602086016020830137856020848301015280955050505050509250925092565b600060018060a01b038416825260206040818401528351806040850152825b8181101561065b5785810183015185820160600152820161063f565b8181111561066c5783606083870101525b50601f01601f191692909201606001949350505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461045f57600080fdfea26469706673582212209be8f39aa1a9dcd75ee50645d6c5a6c6a03ecf17c0cc25eec82607f27237806364736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0xd2001dab6898127be2f167b548691c87251d13c3" + } + }, + "0xd2aAa005d2000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040523480156200001157600080fd5b5060043610620002555760003560e01c80636d6112861162000149578063babc4a3311620000c7578063d547741f1162000086578063d547741f14620005da578063dec2deb614620005f1578063eafd15c81462000606578063edcc12b5146200061d578063f429e383146200063457600080fd5b8063babc4a33146200053f578063c0e312dc146200056d578063ca15c8731462000584578063cb703bff146200059b578063cc5b715b14620005b257600080fd5b80639010d07c11620001145780639010d07c14620004d857806391d1485414620004ef578063a217fddf1462000506578063aebaaca9146200050f578063b9581c50146200053557600080fd5b80636d61128614620004825780636d6c68e614620004965780638504950614620004aa578063884cee5a14620004c157600080fd5b806339927cf911620001d757806350f4428011620001a257806350f4428014620003d3578063510d8a5814620004095780635573b8b6146200044057806368eb202214620004545780636ce681d2146200046b57600080fd5b806339927cf9146200036f5780633b690b6b14620003865780633fa194ce1462000390578063467a5d8114620003a757600080fd5b8063248a9ca31162000224578063248a9ca314620002ee57806328c5e18214620003235780632dc151de146200032d5780632f2ff15d146200034157806336568abe146200035857600080fd5b806301ffc9a7146200025a578063029996b814620002865780630b885ac314620002925780630f1a8f7414620002a9575b600080fd5b620002716200026b36600462003434565b62000657565b60405190151581526020015b60405180910390f35b6200029062000685565b005b62000290620002a336600462003570565b620006dd565b620002d5620002ba36600462003605565b60ce602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016200027d565b62000314620002ff36600462003605565b60009081526065602052604090206001015490565b6040519081526020016200027d565b62000314620006f3565b60ca54620002d5906001600160a01b031681565b62000290620003523660046200361f565b6200073e565b62000290620003693660046200361f565b6200076c565b620002716200038036600462003696565b620007ee565b6200031460cc5481565b6200031460008051602062005f2083398151915281565b620002d5620003b8366004620036db565b60cf602052600090815260409020546001600160a01b031681565b620003fa6040518060400160405280600781526020016613585a5b9b995d60ca1b81525081565b6040516200027d91906200374f565b620002d56200041a3660046200361f565b60d26020908152600092835260408084209091529082529020546001600160a01b031681565b60c954620002d5906001600160a01b031681565b620002906200046536600462003764565b6200084b565b620002906200047c36600462003570565b6200095f565b60cd54620002d5906001600160a01b031681565b60cb54620002d5906001600160a01b031681565b62000290620004bb36600462003793565b62000bd3565b62000290620004d2366004620037f5565b62000e64565b620002d5620004e936600462003856565b62000ff1565b62000271620005003660046200361f565b62001012565b62000314600081565b6200027162000520366004620036db565b60d16020526000908152604090205460ff1681565b620002906200103d565b62000314620005503660046200361f565b60d360209081526000928352604080842090915290825290205481565b620002906200057e36600462003696565b62001086565b620003146200059536600462003605565b620011a4565b62000290620005ac36600462003879565b620011bd565b620003147ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba881565b62000290620005eb3660046200361f565b62001344565b60cd546200027190600160a01b900460ff1681565b6200029062000617366004620038d5565b6200136d565b620002906200062e366004620036db565b6200173a565b6200031462000645366004620036db565b60d06020526000908152604090205481565b60006001600160e01b03198216635a05180f60e01b14806200067f57506200067f8262001856565b92915050565b620006a060008051602062005f208339815191523362001012565b620006c85760405162461bcd60e51b8152600401620006bf9062003944565b60405180910390fd5b60cd805460ff60a01b1916600160a01b179055565b620006ec85858585856200095f565b5050505050565b6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000725919062003985565b6040516020818303038152906040528051906020012081565b6000828152606560205260409020600101546200075b816200188d565b6200076783836200189c565b505050565b6001600160a01b0381163314620007de5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401620006bf565b620007ea8282620018c2565b5050565b6000806001600160a01b031660ce6000858560405160200162000813929190620039a3565b60408051808303601f19018152918152815160209283012083529082019290925201600020546001600160a01b031614159392505050565b60cb54604080518082018252600781526613585a5b9b995d60ca1b60208083019190915291516001600160a01b03909316926359315792926200089092910162003985565b60408051601f198184030181529082905280516020909101206001600160e01b031960e084901b1682526004820152336024820152604401600060405180830381600087803b158015620008e357600080fd5b505af1158015620008f8573d6000803e3d6000fd5b50505050620007ea6040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162000932919062003985565b60408051601f19818403018152919052805160209091012060cd546001600160a01b0316843385620018e8565b600054610100900460ff1615808015620009805750600054600160ff909116105b806200099c5750303b1580156200099c575060005460ff166001145b62000a015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620006bf565b6000805460ff19166001179055801562000a25576000805461ff0019166101001790555b6001600160a01b03821662000a7d5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401620006bf565b62000a8762001e56565b62000a9460003362001ec5565b62000aaf60008051602062005f208339815191523362001ec5565b62000adb7ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001ec5565b8560405160200162000aee919062003985565b60408051601f19818403018152828252805160209182012060cc5560c980546001600160a01b038a81166001600160a01b03199283161790925560ca80548a841690831617905560cb805489841690831617905560cd8054928816929091168217905560008452908301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a1801562000bcb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060405133945090925062000c1f9150849060200162003985565b60408051601f1981840301815282825280516020918201208383018352600784526613585a5b9b995d60ca1b84830152915191935062000c6192910162003985565b60405160208183030381529060405280519060200120810362000ce05760405162461bcd60e51b815260206004820152603060248201527f546869732066756e6374696f6e206973206e6f7420666f72207472616e73666560448201526f1c9c9a5b99c81d1bc813585a5b9b995d60821b6064820152608401620006bf565b6001600160a01b03821662000d385760405162461bcd60e51b815260206004820152601a60248201527f496e636f727265637420726563656976657220616464726573730000000000006044820152606401620006bf565b600081815260ce60205260409020546001600160a01b031662000d9e5760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401620006bf565b6000878760405160200162000db5929190620039a3565b60408051808303601f1901815290829052805160209091012060cb54632c98abc960e11b8352600483018290523360248401529092506001600160a01b031690635931579290604401600060405180830381600087803b15801562000e1957600080fd5b505af115801562000e2e573d6000803e3d6000fd5b505050600082815260ce602052604090205462000e5a915082906001600160a01b0316883389620018e8565b5050505050505050565b60c9546001600160a01b0316331462000ec05760405162461bcd60e51b815260206004820152601c60248201527f53656e646572206973206e6f742061204d65737361676550726f7879000000006044820152606401620006bf565b838360cc54821415801562000edc575062000edc828262001ed1565b62000f2a5760405162461bcd60e51b815260206004820152601b60248201527f526563656976657220636861696e20697320696e636f727265637400000000006044820152606401620006bf565b600062000f38858562001f5c565b90506000600282600e81111562000f535762000f53620039b3565b148062000f745750600482600e81111562000f725762000f72620039b3565b145b8062000f945750600382600e81111562000f925762000f92620039b3565b145b1562000faf5762000fa788878762001fb3565b905062000e5a565b60405162461bcd60e51b815260206004820152601660248201527526b2b9b9b0b3b2aa3cb8329034b9903ab735b737bbb760511b6044820152606401620006bf565b60008281526097602052604081206200100b90836200257f565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6200105860008051602062005f208339815191523362001012565b620010775760405162461bcd60e51b8152600401620006bf9062003944565b60cd805460ff60a01b19169055565b60ca546001600160a01b0316331480620010a85750620010a860003362001012565b620010ee5760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b6044820152606401620006bf565b6000828260405160200162001105929190620039a3565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b0316620011845760405162461bcd60e51b815260206004820152601860248201527f546f6b656e204d616e61676572206973206e6f742073657400000000000000006044820152606401620006bf565b600090815260ce6020526040902080546001600160a01b03191690555050565b60008181526097602052604081206200067f906200258d565b60ca546001600160a01b0316331480620011df5750620011df60003362001012565b620012255760405162461bcd60e51b81526020600482015260156024820152742737ba1030baba3437b934bd32b21031b0b63632b960591b6044820152606401620006bf565b600083836040516020016200123c929190620039a3565b60408051601f198184030181529181528151602092830120600081815260ce9093529120549091506001600160a01b031615620012bc5760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e204d616e6167657220697320616c726561647920736574000000006044820152606401620006bf565b6001600160a01b038216620013145760405162461bcd60e51b815260206004820152601f60248201527f496e636f727265637420546f6b656e204d616e616765722061646472657373006044820152606401620006bf565b600090815260ce6020526040902080546001600160a01b0319166001600160a01b03929092169190911790555050565b60008281526065602052604090206001015462001361816200188d565b620007678383620018c2565b620013997ffda70c2cc66a36c14884ee85424961f51b1d92b4494751699b6d105b3bcbcba83362001012565b620013e75760405162461bcd60e51b815260206004820181905260248201527f544f4b454e5f5245474953545241525f524f4c452069732072657175697265646044820152606401620006bf565b60c954604051634ccd5cd560e11b81526001600160a01b039091169063999ab9aa906200141b9087908790600401620039c9565b602060405180830381865afa15801562001439573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200145f9190620039f8565b620014a65760405162461bcd60e51b815260206004820152601660248201527510da185a5b881a5cc81b9bdd0818dbdb9b9958dd195960521b6044820152606401620006bf565b6001600160a01b0381163b620014ff5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401620006bf565b806001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200153e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001564919062003a1c565b15620015b35760405162461bcd60e51b815260206004820152601760248201527f546f74616c537570706c79206973206e6f74207a65726f0000000000000000006044820152606401620006bf565b60008484604051602001620015ca929190620039a3565b60408051601f198184030181529181528151602092830120600081815260d284528281206001600160a01b0388811683529452919091205490925016156200164e5760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f742072656c696e6b20636c6f6e6560501b6044820152606401620006bf565b6001600160a01b038216600090815260d1602052604090205460ff1615620016b95760405162461bcd60e51b815260206004820152601760248201527f436c6f6e652077617320616c72656164792061646465640000000000000000006044820152606401620006bf565b600081815260d2602090815260408083206001600160a01b0387811680865291845282852080546001600160a01b031916918816918217905580855260d1909352818420805460ff1916600117905590519192909184917f89b97f12155170c72b8eb3449d5f1ba0c6a29e5546051dc35694313b1b60741f91a45050505050565b6200174760003362001012565b620017955760405162461bcd60e51b815260206004820152601e60248201527f44454641554c545f41444d494e5f524f4c4520697320726571756972656400006044820152606401620006bf565b6001600160a01b038116620017ed5760405162461bcd60e51b815260206004820181905260248201527f4465706f736974426f7820616464726573732068617320746f206265207365746044820152606401620006bf565b60cd54604080516001600160a01b03928316815291831660208301527fc968af77923193016f61d74ba6827296db5e1f37ec4fab3ad1ef20e193395e59910160405180910390a160cd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806200067f57506301ffc9a760e01b6001600160e01b03198316146200067f565b62001899813362002598565b50565b620018a8828262002607565b600082815260976020526040902062000767908262002691565b620018ce8282620026a8565b600082815260976020526040902062000767908262002712565b600085815260d2602090815260408083206001600160a01b038088168552925282205416806200198557506001600160a01b038416600090815260d16020526040902054849060ff1615620019805760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e0000000000006044820152606401620006bf565b600191505b6001600160a01b0381163b620019de5760405162461bcd60e51b815260206004820152601860248201527f4e6f20746f6b656e20636c6f6e65206f6e2073636861696e00000000000000006044820152606401620006bf565b6040516370a0823160e01b815233600482015283906001600160a01b038316906370a0823190602401602060405180830381865afa15801562001a25573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a4b919062003a1c565b101562001a905760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b6044820152606401620006bf565b604051636eb1769f60e11b815233600482015230602482015283906001600160a01b0383169063dd62ed3e90604401602060405180830381865afa15801562001add573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b03919062003a1c565b101562001b645760405162461bcd60e51b815260206004820152602860248201527f5472616e73666572206973206e6f7420617070726f76656420627920746f6b6560448201526737103437b63232b960c11b6064820152608401620006bf565b600062001b7386868662002729565b9050821562001cec576040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001bae919062003985565b60405160208183030381529060405280519060200120880362001c305760405162461bcd60e51b815260206004820152603360248201527f4d61696e20636861696e20746f6b656e20636f756c64206e6f74206265207472604482015272185b9cd9995c9959081d1bc813585a5b9b995d606a1b6064820152608401620006bf565b62001c3e888333876200278a565b905062001c4d88838662002906565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd906064016020604051808303816000875af115801562001ca1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cc79190620039f8565b62001ce65760405162461bcd60e51b8152600401620006bf9062003a36565b62001de2565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd906064016020604051808303816000875af115801562001d40573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d669190620039f8565b62001d855760405162461bcd60e51b8152600401620006bf9062003a36565b604051630852cd8d60e31b8152600481018590526001600160a01b038316906342966c6890602401600060405180830381600087803b15801562001dc857600080fd5b505af115801562001ddd573d6000803e3d6000fd5b505050505b60c954604051634a24490160e11b81526001600160a01b039091169063944892029062001e18908b908b90869060040162003a63565b600060405180830381600087803b15801562001e3357600080fd5b505af115801562001e48573d6000803e3d6000fd5b505050505050505050505050565b600054610100900460ff1662001ec35760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620006bf565b565b620007ea82826200189c565b60006040518060400160405280600781526020016613585a5b9b995d60ca1b81525060405160200162001f05919062003985565b60405160208183030381529060405280519060200120831462001f4557600083815260ce60205260409020546001600160a01b038381169116146200100b565b5060cd546001600160a01b03908116911614919050565b60008062001f6d8385018562003605565b905062001f7c60208262003a98565b60000362001fa55762001f9c62001f968483818862003abb565b62001f5c565b9150506200067f565b62001f9c8385018562003afc565b60008062001fc2848462001f5c565b9050600080600062001fd5878762002944565b919450925090506000600285600e81111562001ff55762001ff5620039b3565b1462002354576000600386600e811115620020145762002014620039b3565b036200205d576000620020288a8a62002a04565b60209081015160008d815260d2835260408082206001600160a01b03808b168452945290205490911693509150620021c79050565b60006200206b8a8a62002adf565b60208082015160008e815260d2835260408082206001600160a01b03808c168452945290205490911694509250905082620021c55760cd54600160a01b900460ff16620020fb5760405162461bcd60e51b815260206004820152601c60248201527f4175746f6d61746963206465706c6f792069732064697361626c6564000000006044820152606401620006bf565b8060400151600001518160400151604001516040516200211b9062003426565b6200212892919062003b1a565b604051809103906000f08015801562002145573d6000803e3d6000fd5b5060008c815260d2602090815260408083206001600160a01b038a811680865291845282852080546001600160a01b031916918716918217905580855260d1909352818420805460ff191660011790559051939650909290918e917f817384d3c8c32b58342425cd864f5540355cc93dfbbfc2df8763793d2d3a5e129190a45b505b6001600160a01b038216600090815260d06020526040902054811462002203576001600160a01b038216600090815260d0602052604090208190555b60008062002276846001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002249573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200226f919062003a1c565b8662002bd6565b9092509050818015620022a157506001600160a01b038416600090815260d060205260409020548111155b620022e75760405162461bcd60e51b8152602060048201526015602482015274151bdd185b081cdd5c1c1b1e48195e18d959591959605a1b6044820152606401620006bf565b6040516340c10f1960e01b81526001600160a01b038881166004830152602482018790528516906340c10f1990604401600060405180830381600087803b1580156200233257600080fd5b505af115801562002347573d6000803e3d6000fd5b5050505050505062002523565b6001600160a01b0383163b15158015620023835750600089815260d46020526040902062002383908462002c01565b620023d15760405162461bcd60e51b815260206004820152601a60248201527f496e636f7272656374206d61696e20636861696e20746f6b656e0000000000006044820152606401620006bf565b6040516370a0823160e01b815230600482015282906001600160a01b038516906370a0823190602401602060405180830381865afa15801562002418573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200243e919062003a1c565b1015620024815760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768206d6f6e657960801b6044820152606401620006bf565b6200248e89848462002c24565b60405163a9059cbb60e01b81526001600160a01b0385811660048301526024820184905284169063a9059cbb906044016020604051808303816000875af1158015620024de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620025049190620039f8565b620025235760405162461bcd60e51b8152600401620006bf9062003a36565b806001600160a01b0316836001600160a01b03168a7f131b32ac87206ff25b3250e2d194c4cc6d63e928ab212dbd294b03b49af27b48856040516200256a91815260200190565b60405180910390a45091979650505050505050565b60006200100b838362002c58565b60006200067f825490565b620025a4828262001012565b620007ea57620025bf816001600160a01b0316601462002c85565b620025cc83602062002c85565b604051602001620025df92919062003b43565b60408051601f198184030181529082905262461bcd60e51b8252620006bf916004016200374f565b62002613828262001012565b620007ea5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200264d3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200100b836001600160a01b03841662002e3e565b620026b4828262001012565b15620007ea5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006200100b836001600160a01b03841662002e90565b6040805160a08101825260026080820190815281526001600160a01b038086166020808401919091529085168284015260608083018590529251620027719183910162003c10565b6040516020818303038152906040529150509392505050565b606060008490506000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620027d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620027f8919062003a1c565b905080841115620028425760405162461bcd60e51b8152602060048201526013602482015272105b5bdd5b9d081a5cc81a5b98dbdc9c9958dd606a1b6044820152606401620006bf565b600087815260d4602052604081206200285c908862002c01565b9050806200289b5762002870888862002f94565b620028938787876200288287620030ad565b6200288d8862003114565b62003287565b9350620028b6565b620028b3878787620028ad87620030ad565b620032ff565b93505b866001600160a01b0316887f759c7e29aa34dec4bb9f3af86e647e11cffa0fee371049fd55e8779a2c24484e87604051620028f391815260200190565b60405180910390a3505050949350505050565b600083815260d3602090815260408083206001600160a01b0386168452909152812080548392906200293a90849062003c36565b9091555050505050565b60008060008062002956868662001f5c565b9050600281600e8111156200296f576200296f620039b3565b03620029a257600062002983878762003372565b90508060400151816020015182606001519450945094505050620029fd565b600381600e811115620029b957620029b9620039b3565b03620029ef576000620029cd878762002a04565b51604081015160208201516060909201519096509094509250620029fd915050565b6000620029cd878762002adf565b9250925092565b62002a446040805160e081018252600060c08201818152928201928352606082018190526080820181905260a08201529081908152602001600081525090565b600362002a52848462001f5c565b600e81111562002a665762002a66620039b3565b1462002ad15760405162461bcd60e51b815260206004820152603360248201527f4d6573736167652074797065206973206e6f74204552433230207472616e7366604482015272657220616e6420746f74616c20737570706c7960681b6064820152608401620006bf565b6200100b8284018462003d0f565b62002b3c6040805161010081018252600060e0820181815260608084019182526080840183905260a0840183905260c084018390529083526020808401839052845180830186528281529081019290925281840152909182015290565b600462002b4a848462001f5c565b600e81111562002b5e5762002b5e620039b3565b1462002bc85760405162461bcd60e51b815260206004820152603260248201527f4d6573736167652074797065206973206e6f74204552433230207472616e73666044820152716572207769746820746f6b656e20696e666f60701b6064820152608401620006bf565b6200100b8284018462003d7a565b6000808383018481101562002bf357600080925092505062002bfa565b6001925090505b9250929050565b6001600160a01b038116600090815260018301602052604081205415156200100b565b600083815260d3602090815260408083206001600160a01b0386168452909152812080548392906200293a90849062003e7f565b600082600001828154811062002c725762002c7262003e95565b9060005260206000200154905092915050565b6060600062002c9683600262003eab565b62002ca390600262003c36565b6001600160401b0381111562002cbd5762002cbd62003460565b6040519080825280601f01601f19166020018201604052801562002ce8576020820181803683370190505b509050600360fc1b8160008151811062002d065762002d0662003e95565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062002d385762002d3862003e95565b60200101906001600160f81b031916908160001a905350600062002d5e84600262003eab565b62002d6b90600162003c36565b90505b600181111562002ded576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062002da35762002da362003e95565b1a60f81b82828151811062002dbc5762002dbc62003e95565b60200101906001600160f81b031916908160001a90535060049490941c9362002de58162003ecd565b905062002d6e565b5083156200100b5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620006bf565b600081815260018301602052604081205462002e87575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200067f565b5060006200067f565b6000818152600183016020526040812054801562002f8957600062002eb760018362003e7f565b855490915060009062002ecd9060019062003e7f565b905081811462002f3957600086600001828154811062002ef15762002ef162003e95565b906000526020600020015490508087600001848154811062002f175762002f1762003e95565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002f4d5762002f4d62003ee7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200067f565b60009150506200067f565b6001600160a01b0381163b62002fed5760405162461bcd60e51b815260206004820152601f60248201527f476976656e2061646472657373206973206e6f74206120636f6e7472616374006044820152606401620006bf565b600082815260d46020526040902062003007908262002c01565b15620030565760405162461bcd60e51b815260206004820152601d60248201527f455243323020546f6b656e2077617320616c72656164792061646465640000006044820152606401620006bf565b600082815260d46020526040902062003070908262002691565b506040516000906001600160a01b0383169084907f89b97f12155170c72b8eb3449d5f1ba0c6a29e5546051dc35694313b1b60741f908490a45050565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620030ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200067f919062003a1c565b604080516060808201835280825260006020830152918101919091526040518060600160405280836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200317a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620031a4919081019062003efd565b8152602001836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620031e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200320e919062003f73565b60ff168152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562003255573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200327f919081019062003efd565b905292915050565b6040805161010081018252600460e0820190815260608083019182526001600160a01b03808a166080850152881660a084015260c08301879052908252602080830186905282840185905292519092620032e49183910162003f93565b60405160208183030381529060405291505095945050505050565b6040805160e081018252600360c082019081528183019081526001600160a01b03808816606080850191909152908716608084015260a08301869052908252602080830185905292519092620033589183910162004007565b604051602081830303815290604052915050949350505050565b6040805160a08101825260006080820181815282526020820181905291810182905260608101919091526002620033aa848462001f5c565b600e811115620033be57620033be620039b3565b14620034185760405162461bcd60e51b815260206004820152602260248201527f4d6573736167652074797065206973206e6f74204552433230207472616e736660448201526132b960f11b6064820152608401620006bf565b6200100b828401846200402c565b611ed4806200404c83390190565b6000602082840312156200344757600080fd5b81356001600160e01b0319811681146200100b57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200349b576200349b62003460565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620034cc57620034cc62003460565b604052919050565b60006001600160401b03821115620034f057620034f062003460565b50601f01601f191660200190565b600082601f8301126200351057600080fd5b8135620035276200352182620034d4565b620034a1565b8181528460208386010111156200353d57600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b03811681146200189957600080fd5b600080600080600060a086880312156200358957600080fd5b85356001600160401b03811115620035a057600080fd5b620035ae88828901620034fe565b9550506020860135620035c1816200355a565b93506040860135620035d3816200355a565b92506060860135620035e5816200355a565b91506080860135620035f7816200355a565b809150509295509295909350565b6000602082840312156200361857600080fd5b5035919050565b600080604083850312156200363357600080fd5b82359150602083013562003647816200355a565b809150509250929050565b60008083601f8401126200366557600080fd5b5081356001600160401b038111156200367d57600080fd5b60208301915083602082850101111562002bfa57600080fd5b60008060208385031215620036aa57600080fd5b82356001600160401b03811115620036c157600080fd5b620036cf8582860162003652565b90969095509350505050565b600060208284031215620036ee57600080fd5b81356200100b816200355a565b60005b8381101562003718578181015183820152602001620036fe565b50506000910152565b600081518084526200373b816020860160208601620036fb565b601f01601f19169290920160200192915050565b6020815260006200100b602083018462003721565b600080604083850312156200377857600080fd5b823562003785816200355a565b946020939093013593505050565b60008060008060608587031215620037aa57600080fd5b84356001600160401b03811115620037c157600080fd5b620037cf8782880162003652565b9095509350506020850135620037e5816200355a565b9396929550929360400135925050565b600080600080606085870312156200380c57600080fd5b84359350602085013562003820816200355a565b925060408501356001600160401b038111156200383c57600080fd5b6200384a8782880162003652565b95989497509550505050565b600080604083850312156200386a57600080fd5b50508035926020909101359150565b6000806000604084860312156200388f57600080fd5b83356001600160401b03811115620038a657600080fd5b620038b48682870162003652565b9094509250506020840135620038ca816200355a565b809150509250925092565b60008060008060608587031215620038ec57600080fd5b84356001600160401b038111156200390357600080fd5b620039118782880162003652565b909550935050602085013562003927816200355a565b9150604085013562003939816200355a565b939692955090935050565b60208082526021908201527f4155544f4d415449435f4445504c4f595f524f4c4520697320726571756972656040820152601960fa1b606082015260800190565b6000825162003999818460208701620036fb565b9190910192915050565b8183823760009101908152919050565b634e487b7160e01b600052602160045260246000fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60006020828403121562003a0b57600080fd5b815180151581146200100b57600080fd5b60006020828403121562003a2f57600080fd5b5051919050565b602080825260139082015272151c985b9cd9995c881dd85cc819985a5b1959606a1b604082015260600190565b8381526001600160a01b038316602082015260606040820181905260009062003a8f9083018462003721565b95945050505050565b60008262003ab657634e487b7160e01b600052601260045260246000fd5b500690565b6000808585111562003acc57600080fd5b8386111562003ada57600080fd5b5050820193919092039150565b8035600f811062003af757600080fd5b919050565b60006020828403121562003b0f57600080fd5b6200100b8262003ae7565b60408152600062003b2f604083018562003721565b828103602084015262003a8f818562003721565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162003b7d816017850160208801620036fb565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162003bb0816028840160208801620036fb565b01602801949350505050565b805151600f811062003bde57634e487b7160e01b600052602160045260246000fd5b82526020818101516001600160a01b039081169184019190915260408083015190911690830152606090810151910152565b608081016200067f828462003bbc565b634e487b7160e01b600052601160045260246000fd5b808201808211156200067f576200067f62003c20565b6000818303608081121562003c6057600080fd5b604051608081016001600160401b03828210818311171562003c865762003c8662003460565b81604052829450602084121562003c9c57600080fd5b60a083019350818410818511171562003cb95762003cb962003460565b508260405262003cc98562003ae7565b815281526020840135915062003cdf826200355a565b8160208201526040840135915062003cf7826200355a565b81604082015260608401356060820152505092915050565b600060a0828403121562003d2257600080fd5b604051604081018181106001600160401b038211171562003d475762003d4762003460565b60405262003d56848462003c4c565b815260809290920135602083015250919050565b60ff811681146200189957600080fd5b60006020828403121562003d8d57600080fd5b81356001600160401b038082111562003da557600080fd5b9083019060c0828603121562003dba57600080fd5b62003dc462003476565b62003dd0868462003c4c565b81526080830135602082015260a08301358281111562003def57600080fd5b92909201916060838703121562003e0557600080fd5b62003e0f62003476565b83358381111562003e1f57600080fd5b62003e2d88828701620034fe565b825250602084013562003e408162003d6a565b602082015260408401358381111562003e5857600080fd5b62003e6688828701620034fe565b6040830152508060408301525080935050505092915050565b818103818111156200067f576200067f62003c20565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161562003ec85762003ec862003c20565b500290565b60008162003edf5762003edf62003c20565b506000190190565b634e487b7160e01b600052603160045260246000fd5b60006020828403121562003f1057600080fd5b81516001600160401b0381111562003f2757600080fd5b8201601f8101841362003f3957600080fd5b805162003f4a6200352182620034d4565b81815285602083850101111562003f6057600080fd5b62003a8f826020830160208601620036fb565b60006020828403121562003f8657600080fd5b81516200100b8162003d6a565b6020815262003fa760208201835162003bbc565b602082015160a08201526000604083015160c0808401528051606060e085015262003fd761014085018262003721565b602083015160ff1661010086015260409092015184830360df190161012086015291905062003a8f818362003721565b600060a0820190506200401c82845162003bbc565b6020830151608083015292915050565b6000608082840312156200403f57600080fd5b6200100b838362003c4c56fe60806040523480156200001157600080fd5b5060405162001ed438038062001ed48339810160408190526200003491620005a0565b600054610100900460ff1615808015620000555750600054600160ff909116105b806200008557506200007230620001d960201b620007211760201c565b15801562000085575060005460ff166001145b620000ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000112576000805461ff0019166101001790555b62000127620001e860201b620007301760201c565b6200013e83836200024660201b620007591760201c565b62000153620001e860201b620007301760201c565b6200016e60008051602062001eb483398151915280620002b2565b6200018960008051602062001eb483398151915233620002fd565b8015620001d0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505062000764565b6001600160a01b03163b151590565b600054610100900460ff16620002445760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b565b600054610100900460ff16620002a25760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b620002ae828262000309565b5050565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620002ae828262000387565b600054610100900460ff16620003655760405162461bcd60e51b815260206004820152602b602482015260008051602062001e9483398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000e5565b60cc62000373838262000698565b5060cd62000382828262000698565b505050565b6200039e8282620003c560201b6200078a1760201c565b6000828152609760209081526040909120620003829183906200081062000469821b17901c565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16620002ae5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004253390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000480836001600160a01b03841662000489565b90505b92915050565b6000818152600183016020526040812054620004d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000483565b50600062000483565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200050357600080fd5b81516001600160401b0380821115620005205762000520620004db565b604051601f8301601f19908116603f011681019082821181831017156200054b576200054b620004db565b816040528381526020925086838588010111156200056857600080fd5b600091505b838210156200058c57858201830151818301840152908201906200056d565b600093810190920192909252949350505050565b60008060408385031215620005b457600080fd5b82516001600160401b0380821115620005cc57600080fd5b620005da86838701620004f1565b93506020850151915080821115620005f157600080fd5b506200060085828601620004f1565b9150509250929050565b600181811c908216806200061f57607f821691505b6020821081036200064057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038257600081815260208120601f850160051c810160208610156200066f5750805b601f850160051c820191505b8181101562000690578281556001016200067b565b505050505050565b81516001600160401b03811115620006b457620006b4620004db565b620006cc81620006c584546200060a565b8462000646565b602080601f831160018114620007045760008415620006eb5750858301515b600019600386901b1c1916600185901b17855562000690565b600085815260208120601f198616915b82811015620007355788860151825594840194600190910190840162000714565b5085821015620007545787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61172080620007746000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806370a08231116100c3578063a457c2d71161007c578063a457c2d7146102ef578063a9059cbb14610302578063ca15c87314610315578063d539139314610328578063d547741f1461034f578063dd62ed3e1461036257600080fd5b806370a082311461026557806379cc67901461028e5780639010d07c146102a157806391d14854146102cc57806395d89b41146102df578063a217fddf146102e757600080fd5b80632f2ff15d116101155780632f2ff15d146101f5578063313ce5671461020a57806336568abe14610219578063395093511461022c57806340c10f191461023f57806342966c681461025257600080fd5b806301ffc9a71461015d57806306fdde0314610185578063095ea7b31461019a57806318160ddd146101ad57806323b872dd146101bf578063248a9ca3146101d2575b600080fd5b61017061016b36600461127f565b610375565b60405190151581526020015b60405180910390f35b61018d6103a0565b60405161017c91906112cd565b6101706101a836600461131c565b610432565b60cb545b60405190815260200161017c565b6101706101cd366004611346565b61044a565b6101b16101e0366004611382565b60009081526065602052604090206001015490565b61020861020336600461139b565b61046e565b005b6040516012815260200161017c565b61020861022736600461139b565b610498565b61017061023a36600461131c565b61051b565b61020861024d36600461131c565b61053d565b610208610260366004611382565b6105b6565b6101b16102733660046113c7565b6001600160a01b0316600090815260c9602052604090205490565b61020861029c36600461131c565b6105c3565b6102b46102af3660046113e2565b6105d8565b6040516001600160a01b03909116815260200161017c565b6101706102da36600461139b565b6105f7565b61018d610622565b6101b1600081565b6101706102fd36600461131c565b610631565b61017061031036600461131c565b6106ac565b6101b1610323366004611382565b6106ba565b6101b17f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61020861035d36600461139b565b6106d1565b6101b1610370366004611404565b6106f6565b60006001600160e01b03198216635a05180f60e01b148061039a575061039a82610825565b92915050565b606060cc80546103af9061142e565b80601f01602080910402602001604051908101604052809291908181526020018280546103db9061142e565b80156104285780601f106103fd57610100808354040283529160200191610428565b820191906000526020600020905b81548152906001019060200180831161040b57829003601f168201915b5050505050905090565b60003361044081858561085a565b5060019392505050565b60003361045885828561097e565b6104638585856109f8565b506001949350505050565b60008281526065602052604090206001015461048981610bc6565b6104938383610bd0565b505050565b6001600160a01b038116331461050d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6105178282610bf2565b5050565b60003361044081858561052e83836106f6565b610538919061147e565b61085a565b6105677f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336105f7565b6105ac5760405162461bcd60e51b815260206004820152601660248201527529b2b73232b91034b9903737ba10309026b4b73a32b960511b6044820152606401610504565b6105178282610c14565b6105c03382610cf3565b50565b6105ce82338361097e565b6105178282610cf3565b60008281526097602052604081206105f09083610e41565b9392505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd80546103af9061142e565b6000338161063f82866106f6565b90508381101561069f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610504565b610463828686840361085a565b6000336104408185856109f8565b600081815260976020526040812061039a90610e4d565b6000828152606560205260409020600101546106ec81610bc6565b6104938383610bf2565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6001600160a01b03163b151590565b600054610100900460ff166107575760405162461bcd60e51b815260040161050490611491565b565b600054610100900460ff166107805760405162461bcd60e51b815260040161050490611491565b6105178282610e57565b61079482826105f7565b6105175760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556107cc3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006105f0836001600160a01b038416610e97565b60006001600160e01b03198216637965db0b60e01b148061039a57506301ffc9a760e01b6001600160e01b031983161461039a565b6001600160a01b0383166108bc5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610504565b6001600160a01b03821661091d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610504565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600061098a84846106f6565b905060001981146109f257818110156109e55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610504565b6109f2848484840361085a565b50505050565b6001600160a01b038316610a5c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610504565b6001600160a01b038216610abe5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610504565b6001600160a01b038316600090815260c9602052604090205481811015610b365760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610504565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610b6d90849061147e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610bb991815260200190565b60405180910390a36109f2565b6105c08133610ee6565b610bda828261078a565b60008281526097602052604090206104939082610810565b610bfc8282610f4a565b60008281526097602052604090206104939082610fb1565b6001600160a01b038216610c6a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610504565b8060cb6000828254610c7c919061147e565b90915550506001600160a01b038216600090815260c9602052604081208054839290610ca990849061147e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216610d535760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610504565b6001600160a01b038216600090815260c9602052604090205481811015610dc75760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610504565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610df69084906114dc565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006105f08383610fc6565b600061039a825490565b600054610100900460ff16610e7e5760405162461bcd60e51b815260040161050490611491565b60cc610e8a8382611553565b5060cd6104938282611553565b6000818152600183016020526040812054610ede5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561039a565b50600061039a565b610ef082826105f7565b61051757610f08816001600160a01b03166014610ff0565b610f13836020610ff0565b604051602001610f24929190611613565b60408051601f198184030181529082905262461bcd60e51b8252610504916004016112cd565b610f5482826105f7565b156105175760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006105f0836001600160a01b03841661118c565b6000826000018281548110610fdd57610fdd611688565b9060005260206000200154905092915050565b60606000610fff83600261169e565b61100a90600261147e565b67ffffffffffffffff811115611022576110226114ef565b6040519080825280601f01601f19166020018201604052801561104c576020820181803683370190505b509050600360fc1b8160008151811061106757611067611688565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061109657611096611688565b60200101906001600160f81b031916908160001a90535060006110ba84600261169e565b6110c590600161147e565b90505b600181111561113d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110f9576110f9611688565b1a60f81b82828151811061110f5761110f611688565b60200101906001600160f81b031916908160001a90535060049490941c93611136816116bd565b90506110c8565b5083156105f05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610504565b600081815260018301602052604081205480156112755760006111b06001836114dc565b85549091506000906111c4906001906114dc565b90508181146112295760008660000182815481106111e4576111e4611688565b906000526020600020015490508087600001848154811061120757611207611688565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061123a5761123a6116d4565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061039a565b600091505061039a565b60006020828403121561129157600080fd5b81356001600160e01b0319811681146105f057600080fd5b60005b838110156112c45781810151838201526020016112ac565b50506000910152565b60208152600082518060208401526112ec8160408501602087016112a9565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461131757600080fd5b919050565b6000806040838503121561132f57600080fd5b61133883611300565b946020939093013593505050565b60008060006060848603121561135b57600080fd5b61136484611300565b925061137260208501611300565b9150604084013590509250925092565b60006020828403121561139457600080fd5b5035919050565b600080604083850312156113ae57600080fd5b823591506113be60208401611300565b90509250929050565b6000602082840312156113d957600080fd5b6105f082611300565b600080604083850312156113f557600080fd5b50508035926020909101359150565b6000806040838503121561141757600080fd5b61142083611300565b91506113be60208401611300565b600181811c9082168061144257607f821691505b60208210810361146257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561039a5761039a611468565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8181038181111561039a5761039a611468565b634e487b7160e01b600052604160045260246000fd5b601f82111561049357600081815260208120601f850160051c8101602086101561152c5750805b601f850160051c820191505b8181101561154b57828155600101611538565b505050505050565b815167ffffffffffffffff81111561156d5761156d6114ef565b6115818161157b845461142e565b84611505565b602080601f8311600181146115b6576000841561159e5750858301515b600019600386901b1c1916600185901b17855561154b565b600085815260208120601f198616915b828110156115e5578886015182559484019460019091019084016115c6565b50858210156116035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161164b8160178501602088016112a9565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161167c8160288401602088016112a9565b01602801949350505050565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156116b8576116b8611468565b500290565b6000816116cc576116cc611468565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212202f9e9a6091230d31a1843f8d7bfacf836c46ab8210847934d487741528853dc964736f6c63430008100033496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420699f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67164765a3c8bd2513bdfa0c90f1bee9606e920fbf2c9071f310263fbd818684ba2646970667358221220ebd127e06d6e3b7c0f4a5296b0482b2d6560427a745fbe044dbd8c0b29cd3a9e64736f6c63430008100033", + "nonce": "0x0", + "storage": {} + }, + "0xd2aaa00200000000000000000000000000000000": { + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f9565b610118565b61005b610093366004610713565b610164565b3480156100a457600080fd5b506100ad6101da565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f9565b610217565b3480156100f557600080fd5b506100ad610241565b6101066102a2565b610116610111610346565b610355565b565b610120610379565b6001600160a01b0316336001600160a01b0316141561015957610154816040518060200160405280600081525060006103ac565b610161565b6101616100fe565b50565b61016c610379565b6001600160a01b0316336001600160a01b031614156101cd576101c88383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103ac915050565b6101d5565b6101d56100fe565b505050565b60006101e4610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610346565b9050610214565b6102146100fe565b90565b61021f610379565b6001600160a01b0316336001600160a01b0316141561015957610154816103d7565b600061024b610379565b6001600160a01b0316336001600160a01b0316141561020c57610205610379565b6060610291838360405180606001604052806027815260200161080d6027913961042b565b9392505050565b803b15155b919050565b6102aa610379565b6001600160a01b0316336001600160a01b031614156103415760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b610116565b6000610350610506565b905090565b3660008037600080366000845af43d6000803e808015610374573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316905090565b6103b58361052e565b6000825111806103c25750805b156101d5576103d1838361026c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610400610379565b604080516001600160a01b03928316815291841660208301520160405180910390a16101618161056e565b606061043684610298565b6104915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610338565b600080856001600160a01b0316856040516104ac9190610791565b600060405180830381855af49150503d80600081146104e7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ec565b606091505b50915091506104fc828286610617565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61039d565b61053781610650565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105d35760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610338565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610626575081610291565b8251156106365782518084602001fd5b8160405162461bcd60e51b815260040161033891906107ad565b61065981610298565b6106bb5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610338565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105f6565b80356001600160a01b038116811461029d57600080fd5b60006020828403121561070a578081fd5b610291826106e2565b600080600060408486031215610727578182fd5b610730846106e2565b9250602084013567ffffffffffffffff8082111561074c578384fd5b818601915086601f83011261075f578384fd5b81358181111561076d578485fd5b87602082850101111561077e578485fd5b6020830194508093505050509250925092565b600082516107a38184602087016107e0565b9190910192915050565b60006020825282518060208401526107cc8160408501602087016107e0565b601f01601f19169190910160400192915050565b60005b838110156107fb5781810151838201526020016107e3565b838111156103d1575050600091015256fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c84c60caa2406e5455fa4e91aeba5f4876e6edfc6083972ffa2dc00cf888999464736f6c63430008030033", + "nonce": "0x0", + "storage": { + "0x00": "0x01", + "0x0f4a3aea2306db88f2f635c80bebd5b30ffe00712778585ab059945864347f14": "0x01", + "0x18e31492ad30de9316c3f3bb7486c1aaf78f9bb87d6f8260d74655dab4bcd549": "0x01", + "0x2dd8db9e26b2996e42648eaa4a235e69f68c16392431007c6e963fa26c4b8212": "0xd2001dab6898127be2f167b548691c87251d13c3", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xd2aaa002d2000000000000000000000000000000", + "0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7": "0x01", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xd2aaa00000000000000000000000000000000000" + } + } + }, + "coinbase": "0xd2001DAb6898127Be2F167B548691C87251D13C3", + "config": { + "berlinBlock": 0, + "byzantiumBlock": 0, + "chainId": 210, + "clique": { + "epoch": 30000, + "period": 5 + }, + "constantinopleBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "homesteadBlock": 0, + "istanbulBlock": 0, + "petersburgBlock": 0 + }, + "difficulty": "0x100", + "extradata": "0x0000000000000000000000000000000000000000000000000000000000000000d2001DAb6898127Be2F167B548691C87251D13C30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x8000000", + "nonce": "0x0000000000000033", + "timestamp": "0x0" +} diff --git a/proxy/predeployed/test/prepare_environment.sh b/predeployed/test/prepare_environment.sh similarity index 100% rename from proxy/predeployed/test/prepare_environment.sh rename to predeployed/test/prepare_environment.sh diff --git a/proxy/predeployed/test/requirements.txt b/predeployed/test/requirements.txt similarity index 100% rename from proxy/predeployed/test/requirements.txt rename to predeployed/test/requirements.txt diff --git a/proxy/predeployed/test/test.py b/predeployed/test/test.py similarity index 100% rename from proxy/predeployed/test/test.py rename to predeployed/test/test.py diff --git a/proxy/predeployed/test/test.sh b/predeployed/test/test.sh similarity index 100% rename from proxy/predeployed/test/test.sh rename to predeployed/test/test.sh diff --git a/proxy/predeployed/test/test_generator.py b/predeployed/test/test_generator.py similarity index 100% rename from proxy/predeployed/test/test_generator.py rename to predeployed/test/test_generator.py diff --git a/proxy/predeployed/test/tools.py b/predeployed/test/tools.py similarity index 100% rename from proxy/predeployed/test/tools.py rename to predeployed/test/tools.py diff --git a/predeployed/version.txt b/predeployed/version.txt new file mode 100644 index 000000000..12189c5cc --- /dev/null +++ b/predeployed/version.txt @@ -0,0 +1 @@ +1.3.4a12 diff --git a/proxy/.githooks/pre-commit b/proxy/.githooks/pre-commit deleted file mode 100755 index 7e2979a80..000000000 --- a/proxy/.githooks/pre-commit +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -e - -cd proxy -yarn fullcheck -cd .. diff --git a/proxy/.openzeppelin/project.json b/proxy/.openzeppelin/project.json deleted file mode 100644 index a976bf001..000000000 --- a/proxy/.openzeppelin/project.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "manifestVersion": "2.2", - "contracts": { - "MessageProxyForMainnet": "MessageProxyForMainnet", - "Linker": "Linker", - "DepositBoxEth": "DepositBoxEth", - "DepositBoxERC20": "DepositBoxERC20", - "DepositBoxERC721": "DepositBoxERC721", - "CommunityPool": "CommunityPool" - }, - "dependencies": {}, - "name": "skale-ima-proxy", - "version": "1.0.0", - "compiler": { - "compilerSettings": { - "optimizer": { - "enabled": true, - "runs": "200" - } - }, - "typechain": { - "enabled": false - }, - "manager": "openzeppelin", - "artifactsDir": "build/contracts", - "contractsDir": "contracts", - "solcVersion": "0.6.12" - }, - "telemetryOptIn": false -} diff --git a/proxy/README.md b/proxy/README.md deleted file mode 100644 index 2324914ae..000000000 --- a/proxy/README.md +++ /dev/null @@ -1,124 +0,0 @@ - - -[![codecov](https://codecov.io/gh/skalenetwork/IMA/branch/develop/graph/badge.svg?token=rprj0137UA)](https://codecov.io/gh/skalenetwork/IMA) - -# SKALE IMA Proxy - -SKALE Interchain Messaging Smart Contracts - -Proxy is a library with smart contracts for the SKALE Interchain Messaging Agent. This system allows transferring ETH, ERC20 and ERC721 and is based on the Message Proxy system. - -Smart contract language - Solidity 0.5.10 -NodeJS version - 10.16.0 -NPM version - 6.9.0 - -## Message Proxy system - -This system allows sending and receiving messages from other chains. `MessageProxy.sol` contract needs to be deployed to Mainnet, and deployed to each SKALE chain to use it with the SKALE Interchain Messaging Agent. -You can use MessageProxy contract separately by Interchain Messaging Smart Contracts: - -1) Add interface: - -```solidity -interface Proxy { - function postOutgoingMessage( - string calldata targetSchainName, - address targetContract, - uint256 amount, - address to, - bytes calldata data - ) - external; -} -``` - -2) Write `postMessage` function, which will receive and process messages from other chains: - -```solidity -function postMessage( - address sender, - string memory fromSchainName, - address payable to, - uint256 amount, - bytes memory data -) - public -{ - ... -} -``` - -3) Add the address of MessageProxy on some chain: - Data of Smart contracts stores in `data` folder - -4) Then continue developing your dApp - -## Ether clone on SKALE chain - -There is a Wrapped Ether clone(EthERC20.sol) on SKALE chains - it is an ERC20 token and inherits the known ERC-20 approve issue. Please find more details here https://blog.smartdec.net/erc20-approve-issue-in-simple-words-a41aaf47bca6 - -## Interchain Messaging Agent system - -This system sends and receives ETH, ERC20, and ERC721 tokens from other chains. -It consists of 3 additional smart contracts (not including MessageProxy contract): - -1) `DepositBox.sol` - contract only on a mainnet: DepositBox can transfer ETH and ERC20, ERC721 tokens to other chains. \- `deposit(string memory schainName, address to)` - transfer ETH. ... -2) `TokenManager.sol` -3) `TokenFactory.sol` - -## Install - -1) Clone this repo -2) run `npm install` -3) run `npm start`, this command will compile contracts - -## Deployment - -Configure your networks for SKALE chain and mainnet in `truffle-config.js` - -There are several example networks in comments. - -The `.env` file should include the following variables: - -```bash -URL_W3_ETHEREUM="your mainnet RPC url, it also can be an infura endpoint" -URL_W3_S_CHAIN="your SKALE chain RPC url, it also can be an infura endpoint" -CHAIN_NAME_SCHAIN="your SKALE chain name" -PRIVATE_KEY_FOR_ETHEREUM="your private key for mainnet" -PRIVATE_KEY_FOR_SCHAIN="your private key for SKALE chain" -ACCOUNT_FOR_ETHEREUM="your account for mainnet" -ACCOUNT_FOR_SCHAIN="your account for SKALE chain" -NETWORK_FOR_ETHEREUM="your created network for mainnet" -NETWORK_FOR_SCHAIN="your created network for SKALE chain" -``` - -- deploy only to your mainnet: - -```bash -npm run deploy-to-mainnet -``` - -- deploy only to your schain: - -```bash -npm run deploy-to-schain -``` - -- deploy only to your mainnet and to schain: - -```bash -npm run deploy-to-both -``` - -### Generate IMA data file for skale-node - -Results will be saved to `[RESULTS_FOLDER]/ima_data.json` - -- `ARTIFACTS_FOLDER` - path to `build/contracts` folder -- `RESULTS_FOLDER` - path to the folder where `ima_data.json` will be saved - -```bash -cd proxy -npm run compile -python ima_datafile_generator.py [ARTIFACTS_FOLDER] [RESULTS_FOLDER] -``` diff --git a/proxy/package.json b/proxy/package.json deleted file mode 100644 index 45dd74230..000000000 --- a/proxy/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "skale-ima-proxy", - "private": true, - "license": "AGPL-3.0", - "author": "SKALE Labs and contributors", - "scripts": { - "compile": "npx hardhat compile", - "cleanCompile": "npx hardhat clean && yarn compile", - "deploy-to-both-chains": "yarn deploy-to-mainnet && yarn deploy-to-schain", - "deploy-to-mainnet": "VERSION=$(cat ../VERSION) npx hardhat run migrations/deployMainnet.ts --network mainnet", - "deploy-to-schain": "VERSION=$(cat ../VERSION) npx hardhat run migrations/deploySchain.ts --network schain", - "deploy-skale-manager-components": "npx hardhat run migrations/deploySkaleManagerComponents.ts --network mainnet", - "eslint": "npx eslint .", - "lint": "npx solhint \"contracts/**/*.sol\"", - "prepare": "yarn cleanCompile", - "test": "yarn tsc && npx hardhat test", - "tsc": "tsc --noEmit", - "slither": "slither .", - "fullcheck": "yarn lint && yarn tsc && yarn eslint && yarn slither", - "hooks": "git config core.hooksPath proxy/.githooks", - "no-hooks": "git config core.hooksPath .git/hooks" - }, - "dependencies": { - "@nomiclabs/hardhat-ethers": "^2.1.0", - "@openzeppelin/contracts-upgradeable": "^4.7.1", - "@openzeppelin/hardhat-upgrades": "^1.14.0", - "@skalenetwork/etherbase-interfaces": "^0.0.1-develop.20", - "@skalenetwork/ima-interfaces": "2.0.0", - "@skalenetwork/skale-manager-interfaces": "2.0.0", - "@skalenetwork/upgrade-tools": "^2.0.2", - "axios": "^0.21.4", - "dotenv": "^16.0.0", - "ethers": "^5.7.2", - "hardhat": "2.11.0 - 2.16.1" - }, - "devDependencies": { - "@nomiclabs/hardhat-etherscan": "^3.1.0", - "@nomiclabs/hardhat-waffle": "^2.0.2", - "@typechain/ethers-v5": "^11.1.1", - "@typechain/hardhat": "^7.0.0", - "@types/chai": "^4.2.12", - "@types/chai-almost": "^1.0.1", - "@types/chai-as-promised": "^7.1.3", - "@types/elliptic": "^6.4.14", - "@types/minimist": "^1.2.0", - "@types/mocha": "^9.1.0", - "@types/sinon-chai": "^3.2.5", - "@typescript-eslint/eslint-plugin": "^6.2.1", - "@typescript-eslint/parser": "^6.2.1", - "chai": "^4.2.0", - "chai-almost": "^1.0.1", - "chai-as-promised": "^7.1.1", - "eslint": "^8.46.0", - "ethereum-waffle": "^4.0.10", - "ganache": "7.9.2", - "solhint": "3.3.6", - "solidity-coverage": "^0.8.4", - "ts-generator": "^0.1.1", - "ts-node": "^8.10.2", - "typechain": "^8.3.1", - "typescript": "^5.1.6" - } -} diff --git a/proxy/yarn.lock b/proxy/yarn.lock deleted file mode 100644 index 73b7af7b1..000000000 --- a/proxy/yarn.lock +++ /dev/null @@ -1,7321 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@aws-crypto/sha256-js@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz#02acd1a1fda92896fc5a28ec7c6e164644ea32fc" - integrity sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g== - dependencies: - "@aws-crypto/util" "^1.2.2" - "@aws-sdk/types" "^3.1.0" - tslib "^1.11.1" - -"@aws-crypto/util@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-1.2.2.tgz#b28f7897730eb6538b21c18bd4de22d0ea09003c" - integrity sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg== - dependencies: - "@aws-sdk/types" "^3.1.0" - "@aws-sdk/util-utf8-browser" "^3.0.0" - tslib "^1.11.1" - -"@aws-sdk/types@^3.1.0": - version "3.378.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.378.0.tgz#93a811ccdf15c81b1947f1cd67922c4690792189" - integrity sha512-qP0CvR/ItgktmN8YXpGQglzzR/6s0nrsQ4zIfx3HMwpsBTwuouYahcCtF1Vr82P4NFcoDA412EJahJ2pIqEd+w== - dependencies: - "@smithy/types" "^2.0.2" - tslib "^2.5.0" - -"@aws-sdk/util-utf8-browser@^3.0.0": - version "3.259.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" - integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== - dependencies: - tslib "^2.3.1" - -"@babel/code-frame@^7.0.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/helper-validator-identifier@^7.14.5": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== - -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - -"@chainsafe/persistent-merkle-tree@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" - integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/persistent-merkle-tree@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" - integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/ssz@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" - -"@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.6.2" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" - integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== - -"@eslint/eslintrc@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.1.tgz#18d635e24ad35f7276e8a49d135c7d3ca6a46f93" - integrity sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@^8.46.0": - version "8.46.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.46.0.tgz#3f7802972e8b6fe3f88ed1aabc74ec596c456db6" - integrity sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA== - -"@ethereum-waffle/chai@4.0.10": - version "4.0.10" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-4.0.10.tgz#6f600a40b6fdaed331eba42b8625ff23f3a0e59a" - integrity sha512-X5RepE7Dn8KQLFO7HHAAe+KeGaX/by14hn90wePGBhzL54tq4Y8JscZFu+/LCwCl6TnkAAy5ebiMoqJ37sFtWw== - dependencies: - "@ethereum-waffle/provider" "4.0.5" - debug "^4.3.4" - json-bigint "^1.0.0" - -"@ethereum-waffle/compiler@4.0.3": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-4.0.3.tgz#069e2df24b879b8a7b78857bad6f8bf6ebc8a5b1" - integrity sha512-5x5U52tSvEVJS6dpCeXXKvRKyf8GICDwiTwUvGD3/WD+DpvgvaoHOL82XqpTSUHgV3bBq6ma5/8gKUJUIAnJCw== - dependencies: - "@resolver-engine/imports" "^0.3.3" - "@resolver-engine/imports-fs" "^0.3.3" - "@typechain/ethers-v5" "^10.0.0" - "@types/mkdirp" "^0.5.2" - "@types/node-fetch" "^2.6.1" - mkdirp "^0.5.1" - node-fetch "^2.6.7" - -"@ethereum-waffle/ens@4.0.3": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-4.0.3.tgz#4a46ac926414f3c83b4e8cc2562c8e2aee06377a" - integrity sha512-PVLcdnTbaTfCrfSOrvtlA9Fih73EeDvFS28JQnT5M5P4JMplqmchhcZB1yg/fCtx4cvgHlZXa0+rOCAk2Jk0Jw== - -"@ethereum-waffle/mock-contract@4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-4.0.4.tgz#f13fea29922d87a4d2e7c4fc8fe72ea04d2c13de" - integrity sha512-LwEj5SIuEe9/gnrXgtqIkWbk2g15imM/qcJcxpLyAkOj981tQxXmtV4XmQMZsdedEsZ/D/rbUAOtZbgwqgUwQA== - -"@ethereum-waffle/provider@4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-4.0.5.tgz#8a65dbf0263f4162c9209608205dee1c960e716b" - integrity sha512-40uzfyzcrPh+Gbdzv89JJTMBlZwzya1YLDyim8mVbEqYLP5VRYWoGp0JMyaizgV3hMoUFRqJKVmIUw4v7r3hYw== - dependencies: - "@ethereum-waffle/ens" "4.0.3" - "@ganache/ethereum-options" "0.1.4" - debug "^4.3.4" - ganache "7.4.3" - -"@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.0", "@ethereumjs/block@^3.6.2": - version "3.6.3" - resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.3.tgz#d96cbd7af38b92ebb3424223dbf773f5ccd27f84" - integrity sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg== - dependencies: - "@ethereumjs/common" "^2.6.5" - "@ethereumjs/tx" "^3.5.2" - ethereumjs-util "^7.1.5" - merkle-patricia-tree "^4.2.4" - -"@ethereumjs/blockchain@^5.5.0": - version "5.5.3" - resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz#aa49a6a04789da6b66b5bcbb0d0b98efc369f640" - integrity sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw== - dependencies: - "@ethereumjs/block" "^3.6.2" - "@ethereumjs/common" "^2.6.4" - "@ethereumjs/ethash" "^1.1.0" - debug "^4.3.3" - ethereumjs-util "^7.1.5" - level-mem "^5.0.1" - lru-cache "^5.1.1" - semaphore-async-await "^1.5.1" - -"@ethereumjs/common@2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.0.tgz#feb96fb154da41ee2cc2c5df667621a440f36348" - integrity sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA== - dependencies: - crc-32 "^1.2.0" - ethereumjs-util "^7.1.3" - -"@ethereumjs/common@^2.6.0", "@ethereumjs/common@^2.6.4", "@ethereumjs/common@^2.6.5": - version "2.6.5" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" - integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== - dependencies: - crc-32 "^1.2.0" - ethereumjs-util "^7.1.5" - -"@ethereumjs/ethash@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-1.1.0.tgz#7c5918ffcaa9cb9c1dc7d12f77ef038c11fb83fb" - 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" - -"@ethereumjs/tx@3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.4.0.tgz#7eb1947eefa55eb9cf05b3ca116fb7a3dbd0bce7" - integrity sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw== - dependencies: - "@ethereumjs/common" "^2.6.0" - ethereumjs-util "^7.1.3" - -"@ethereumjs/tx@^3.4.0", "@ethereumjs/tx@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c" - integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw== - dependencies: - "@ethereumjs/common" "^2.6.4" - ethereumjs-util "^7.1.5" - -"@ethereumjs/vm@5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.6.0.tgz#e0ca62af07de820143674c30b776b86c1983a464" - 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" - -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abi@^5.1.2": - version "5.4.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.1.tgz#6ac28fafc9ef6f5a7a37e30356a2eb31fa05d39b" - integrity sha512-9mhbjUk76BiSluiiW4BaYyI58KSbDMMQpCLdsAR+RsT2GyATiNYxVv+pGWRrekmsIdY3I+hOqsYQSTkc8L/mcg== - dependencies: - "@ethersproject/address" "^5.4.0" - "@ethersproject/bignumber" "^5.4.0" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/constants" "^5.4.0" - "@ethersproject/hash" "^5.4.0" - "@ethersproject/keccak256" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/properties" "^5.4.0" - "@ethersproject/strings" "^5.4.0" - -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-provider@^5.4.0": - version "5.4.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz#e404309a29f771bd4d28dbafadcaa184668c2a6e" - integrity sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ== - dependencies: - "@ethersproject/bignumber" "^5.4.0" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/networks" "^5.4.0" - "@ethersproject/properties" "^5.4.0" - "@ethersproject/transactions" "^5.4.0" - "@ethersproject/web" "^5.4.0" - -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/abstract-signer@^5.4.0": - version "5.4.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz#e4e9abcf4dd4f1ba0db7dff9746a5f78f355ea81" - integrity sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA== - dependencies: - "@ethersproject/abstract-provider" "^5.4.0" - "@ethersproject/bignumber" "^5.4.0" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/properties" "^5.4.0" - -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/address@^5.0.2", "@ethersproject/address@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.4.0.tgz#ba2d00a0f8c4c0854933b963b9a3a9f6eb4a37a3" - integrity sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q== - dependencies: - "@ethersproject/bignumber" "^5.4.0" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/keccak256" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/rlp" "^5.4.0" - -"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/base64@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.4.0.tgz#7252bf65295954c9048c7ca5f43e5c86441b2a9a" - integrity sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ== - dependencies: - "@ethersproject/bytes" "^5.4.0" - -"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - -"@ethersproject/bignumber@^5.4.0": - version "5.4.2" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.4.2.tgz#44232e015ae4ce82ac034de549eb3583c71283d8" - integrity sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA== - dependencies: - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - bn.js "^4.11.9" - -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/bytes@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.4.0.tgz#56fa32ce3bf67153756dbaefda921d1d4774404e" - integrity sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA== - dependencies: - "@ethersproject/logger" "^5.4.0" - -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/constants@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.4.0.tgz#ee0bdcb30bf1b532d2353c977bf2ef1ee117958a" - integrity sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q== - dependencies: - "@ethersproject/bignumber" "^5.4.0" - -"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" - integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== - dependencies: - "@ethersproject/abi" "^5.7.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hash@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.4.0.tgz#d18a8e927e828e22860a011f39e429d388344ae0" - integrity sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA== - dependencies: - "@ethersproject/abstract-signer" "^5.4.0" - "@ethersproject/address" "^5.4.0" - "@ethersproject/bignumber" "^5.4.0" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/keccak256" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/properties" "^5.4.0" - "@ethersproject/strings" "^5.4.0" - -"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - -"@ethersproject/keccak256@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.4.0.tgz#7143b8eea4976080241d2bd92e3b1f1bf7025318" - integrity sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A== - dependencies: - "@ethersproject/bytes" "^5.4.0" - js-sha3 "0.5.7" - -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - -"@ethersproject/logger@^5.4.0": - version "5.4.1" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.4.1.tgz#503bd33683538b923c578c07d1c2c0dd18672054" - integrity sha512-DZ+bRinnYLPw1yAC64oRl0QyVZj43QeHIhVKfD/+YwSz4wsv1pfwb5SOFjz+r710YEWzU6LrhuSjpSO+6PeE4A== - -"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/networks@^5.4.0": - version "5.4.2" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.4.2.tgz#2247d977626e97e2c3b8ee73cd2457babde0ce35" - integrity sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw== - dependencies: - "@ethersproject/logger" "^5.4.0" - -"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/properties@^5.4.0": - version "5.4.1" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.4.1.tgz#9f051f976ce790142c6261ccb7b826eaae1f2f36" - integrity sha512-cyCGlF8wWlIZyizsj2PpbJ9I7rIlUAfnHYwy/T90pdkSn/NFTa5YWZx2wTJBe9V7dD65dcrrEMisCRUJiq6n3w== - dependencies: - "@ethersproject/logger" "^5.4.0" - -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": - version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" - integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.4.0.tgz#de61afda5ff979454e76d3b3310a6c32ad060931" - integrity sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg== - dependencies: - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - -"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/signing-key@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.4.0.tgz#2f05120984e81cf89a3d5f6dec5c68ee0894fbec" - integrity sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A== - dependencies: - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/properties" "^5.4.0" - bn.js "^4.11.9" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/solidity@5.7.0", "@ethersproject/solidity@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" - integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/strings@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.4.0.tgz#fb12270132dd84b02906a8d895ae7e7fa3d07d9a" - integrity sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA== - dependencies: - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/constants" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/transactions@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.4.0.tgz#a159d035179334bd92f340ce0f77e83e9e1522e0" - integrity sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ== - dependencies: - "@ethersproject/address" "^5.4.0" - "@ethersproject/bignumber" "^5.4.0" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/constants" "^5.4.0" - "@ethersproject/keccak256" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/properties" "^5.4.0" - "@ethersproject/rlp" "^5.4.0" - "@ethersproject/signing-key" "^5.4.0" - -"@ethersproject/units@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" - integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/wallet@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/web@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.4.0.tgz#49fac173b96992334ed36a175538ba07a7413d1f" - integrity sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og== - dependencies: - "@ethersproject/base64" "^5.4.0" - "@ethersproject/bytes" "^5.4.0" - "@ethersproject/logger" "^5.4.0" - "@ethersproject/properties" "^5.4.0" - "@ethersproject/strings" "^5.4.0" - -"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ganache/ethereum-address@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@ganache/ethereum-address/-/ethereum-address-0.1.4.tgz#0e6d66f4a24f64bf687cb3ff7358fb85b9d9005e" - integrity sha512-sTkU0M9z2nZUzDeHRzzGlW724xhMLXo2LeX1hixbnjHWY1Zg1hkqORywVfl+g5uOO8ht8T0v+34IxNxAhmWlbw== - dependencies: - "@ganache/utils" "0.1.4" - -"@ganache/ethereum-options@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@ganache/ethereum-options/-/ethereum-options-0.1.4.tgz#6a559abb44225e2b8741a8f78a19a46714a71cd6" - integrity sha512-i4l46taoK2yC41FPkcoDlEVoqHS52wcbHPqJtYETRWqpOaoj9hAg/EJIHLb1t6Nhva2CdTO84bG+qlzlTxjAHw== - dependencies: - "@ganache/ethereum-address" "0.1.4" - "@ganache/ethereum-utils" "0.1.4" - "@ganache/options" "0.1.4" - "@ganache/utils" "0.1.4" - bip39 "3.0.4" - seedrandom "3.0.5" - -"@ganache/ethereum-utils@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@ganache/ethereum-utils/-/ethereum-utils-0.1.4.tgz#fae4b5b9e642e751ff1fa0cd7316c92996317257" - integrity sha512-FKXF3zcdDrIoCqovJmHLKZLrJ43234Em2sde/3urUT/10gSgnwlpFmrv2LUMAmSbX3lgZhW/aSs8krGhDevDAg== - dependencies: - "@ethereumjs/common" "2.6.0" - "@ethereumjs/tx" "3.4.0" - "@ethereumjs/vm" "5.6.0" - "@ganache/ethereum-address" "0.1.4" - "@ganache/rlp" "0.1.4" - "@ganache/utils" "0.1.4" - emittery "0.10.0" - ethereumjs-abi "0.6.8" - ethereumjs-util "7.1.3" - -"@ganache/options@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@ganache/options/-/options-0.1.4.tgz#325b07e6de85094667aaaaf3d653e32404a04b78" - integrity sha512-zAe/craqNuPz512XQY33MOAG6Si1Xp0hCvfzkBfj2qkuPcbJCq6W/eQ5MB6SbXHrICsHrZOaelyqjuhSEmjXRw== - dependencies: - "@ganache/utils" "0.1.4" - bip39 "3.0.4" - seedrandom "3.0.5" - -"@ganache/rlp@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@ganache/rlp/-/rlp-0.1.4.tgz#f4043afda83e1a14a4f80607b103daf166a9b374" - integrity sha512-Do3D1H6JmhikB+6rHviGqkrNywou/liVeFiKIpOBLynIpvZhRCgn3SEDxyy/JovcaozTo/BynHumfs5R085MFQ== - dependencies: - "@ganache/utils" "0.1.4" - rlp "2.2.6" - -"@ganache/utils@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@ganache/utils/-/utils-0.1.4.tgz#25d60d7689e3dda6a8a7ad70e3646f07c2c39a1f" - integrity sha512-oatUueU3XuXbUbUlkyxeLLH3LzFZ4y5aSkNbx6tjSIhVTPeh+AuBKYt4eQ73FFcTB3nj/gZoslgAh5CN7O369w== - dependencies: - emittery "0.10.0" - keccak "3.0.1" - seedrandom "3.0.5" - optionalDependencies: - "@trufflesuite/bigint-buffer" "1.1.9" - -"@humanwhocodes/config-array@^0.11.10": - version "0.11.10" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@metamask/eth-sig-util@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" - 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" - -"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" - integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== - -"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nomicfoundation/ethereumjs-block@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz#6f89664f55febbd723195b6d0974773d29ee133d" - integrity sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - -"@nomicfoundation/ethereumjs-blockchain@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz#80e0bd3535bfeb9baa29836b6f25123dab06a726" - integrity sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-ethash" "3.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz#4702d82df35b07b5407583b54a45bf728e46a2f0" - integrity sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.1" - crc-32 "^1.2.0" - -"@nomicfoundation/ethereumjs-ethash@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz#65ca494d53e71e8415c9a49ef48bc921c538fc41" - integrity sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - bigint-crypto-utils "^3.0.23" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz#f35681e203363f69ce2b3d3bf9f44d4e883ca1f1" - integrity sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ== - dependencies: - "@ethersproject/providers" "^5.7.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/ethereumjs-rlp@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz#0b30c1cf77d125d390408e391c4bb5291ef43c28" - integrity sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ== - -"@nomicfoundation/ethereumjs-statemanager@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz#8824a97938db4471911e2d2f140f79195def5935" - integrity sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" - -"@nomicfoundation/ethereumjs-trie@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz#662c55f6b50659fd4b22ea9f806a7401cafb7717" - integrity sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz#7629dc2036b4a33c34e9f0a592b43227ef4f0c7d" - integrity sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w== - dependencies: - "@chainsafe/ssz" "^0.9.2" - "@ethersproject/providers" "^5.7.2" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz#530cda8bae33f8b5020a8f199ed1d0a2ce48ec89" - integrity sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA== - dependencies: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-vm@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz#7d035e0993bcad10716c8b36e61dfb87fa3ca05f" - integrity sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-blockchain" "7.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-evm" "2.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-statemanager" "2.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" - integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== - -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" - integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== - -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" - integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" - integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== - -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" - integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== - -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" - integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== - -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" - integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== - -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" - integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== - -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" - integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== - -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" - integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== - -"@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" - integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== - optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" - -"@nomiclabs/hardhat-ethers@^2.1.0": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz#b41053e360c31a32c2640c9a45ee981a7e603fe0" - integrity sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg== - -"@nomiclabs/hardhat-etherscan@^3.1.0": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" - integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - fs-extra "^7.0.1" - lodash "^4.17.11" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - -"@nomiclabs/hardhat-waffle@^2.0.2": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz#d11cb063a5f61a77806053e54009c40ddee49a54" - integrity sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg== - -"@openzeppelin/contracts-upgradeable@^4.4.2": - version "4.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz#26688982f46969018e3ed3199e72a07c8d114275" - integrity sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w== - -"@openzeppelin/contracts-upgradeable@^4.7.1": - version "4.7.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.1.tgz#f63fc384255d6ac139e0a2561aa207fd7c14183c" - integrity sha512-5EFiZld3DYFd8aTL8eeMnhnaWh1/oXLXFNuFMrgF3b1DNPshF3LCyO7VR6lc+gac2URJ0BlVcZoCfkk/3MoEfg== - -"@openzeppelin/defender-base-client@^1.46.0": - version "1.47.1" - resolved "https://registry.yarnpkg.com/@openzeppelin/defender-base-client/-/defender-base-client-1.47.1.tgz#2044fd048d73778a42eb0c5ae6f1370d0ab4bac9" - integrity sha512-xnopi1tZIh1zY9KF3mo9S2YgMP0I3T11r6jiO1teAw6M0U5Fx2SCjfCVoKV7CLAQGH1VHmAZ7w2CmcEsFvlQng== - dependencies: - amazon-cognito-identity-js "^6.0.1" - async-retry "^1.3.3" - axios "^1.4.0" - lodash "^4.17.19" - node-fetch "^2.6.0" - -"@openzeppelin/hardhat-upgrades@^1.14.0": - version "1.28.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.28.0.tgz#6361f313a8a879d8a08a5e395acf0933bc190950" - integrity sha512-7sb/Jf+X+uIufOBnmHR0FJVWuxEs2lpxjJnLNN6eCJCP8nD0v+Ot5lTOW2Qb/GFnh+fLvJtEkhkowz4ZQ57+zQ== - dependencies: - "@openzeppelin/defender-base-client" "^1.46.0" - "@openzeppelin/platform-deploy-client" "^0.8.0" - "@openzeppelin/upgrades-core" "^1.27.0" - chalk "^4.1.0" - debug "^4.1.1" - proper-lockfile "^4.1.1" - -"@openzeppelin/platform-deploy-client@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/platform-deploy-client/-/platform-deploy-client-0.8.0.tgz#af6596275a19c283d6145f0128cc1247d18223c1" - integrity sha512-POx3AsnKwKSV/ZLOU/gheksj0Lq7Is1q2F3pKmcFjGZiibf+4kjGxr4eSMrT+2qgKYZQH1ZLQZ+SkbguD8fTvA== - dependencies: - "@ethersproject/abi" "^5.6.3" - "@openzeppelin/defender-base-client" "^1.46.0" - axios "^0.21.2" - lodash "^4.17.19" - node-fetch "^2.6.0" - -"@openzeppelin/upgrades-core@^1.27.0": - version "1.27.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.27.3.tgz#d5578e3a3ccd18a61fc585945be67951480238b5" - integrity sha512-IqlSMUkno1XKF4L46aUqZ4BqHxj4dF0BRGrFcKeG2Q0vrsKoazhY67JG9bO+wMYG4zxl6jgmG0bd5ef9HLcLmw== - dependencies: - cbor "^8.0.0" - chalk "^4.1.0" - compare-versions "^6.0.0" - debug "^4.1.1" - ethereumjs-util "^7.0.3" - minimist "^1.2.7" - proper-lockfile "^4.1.1" - solidity-ast "^0.4.15" - -"@resolver-engine/core@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" - integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== - dependencies: - debug "^3.1.0" - is-url "^1.2.4" - request "^2.85.0" - -"@resolver-engine/fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" - integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== - dependencies: - "@resolver-engine/core" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports-fs@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" - integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== - dependencies: - "@resolver-engine/fs" "^0.3.3" - "@resolver-engine/imports" "^0.3.3" - debug "^3.1.0" - -"@resolver-engine/imports@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" - integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== - 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" - -"@safe-global/safe-core-sdk-types@^1.9.0", "@safe-global/safe-core-sdk-types@^1.9.2": - version "1.10.1" - resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk-types/-/safe-core-sdk-types-1.10.1.tgz#94331b982671d2f2b8cc23114c58baf63d460c81" - integrity sha512-BKvuYTLOlY16Rq6qCXglmnL6KxInDuXMFqZMaCzwDKiEh+uoHu3xCumG5tVtWOkCgBF4XEZXMqwZUiLcon7IsA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/contracts" "^5.7.0" - "@safe-global/safe-deployments" "^1.20.2" - web3-core "^1.8.1" - web3-utils "^1.8.1" - -"@safe-global/safe-core-sdk-utils@^1.7.4": - version "1.7.4" - resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk-utils/-/safe-core-sdk-utils-1.7.4.tgz#810d36cf9629129a28eb1b9c6e690b163834b572" - integrity sha512-ITocwSWlFUA1K9VMP/eJiMfgbP/I9qDxAaFz7ukj5N5NZD3ihVQZkmqML6hjse5UhrfjCnfIEcLkNZhtB2XC2Q== - dependencies: - "@safe-global/safe-core-sdk-types" "^1.9.2" - semver "^7.3.8" - web3-utils "^1.8.1" - -"@safe-global/safe-core-sdk@^3.3.2": - version "3.3.4" - resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk/-/safe-core-sdk-3.3.4.tgz#d404287f9b910feab3e692243aaf62494ff2d2a9" - integrity sha512-tgcK7VWo66Z8632xaYDzUHQ8InPOaI10ELk1wCrO/C3QjPwxjIozbMGOMzF4RZPCSJX2YAHowAvOgmEukgSkxA== - dependencies: - "@ethersproject/solidity" "^5.7.0" - "@safe-global/safe-core-sdk-types" "^1.9.2" - "@safe-global/safe-core-sdk-utils" "^1.7.4" - "@safe-global/safe-deployments" "^1.25.0" - ethereumjs-util "^7.1.5" - semver "^7.3.8" - web3-utils "^1.8.1" - -"@safe-global/safe-deployments@^1.20.2", "@safe-global/safe-deployments@^1.25.0": - version "1.26.0" - resolved "https://registry.yarnpkg.com/@safe-global/safe-deployments/-/safe-deployments-1.26.0.tgz#b83615b3b5a66e736e08f8ecf2801ed988e9e007" - integrity sha512-Tw89O4/paT19ieMoiWQbqRApb0Bef/DxweS9rxodXAM5EQModkbyFXGZca+YxXE67sLvWjLr2jJUOxwze8mhGw== - dependencies: - semver "^7.3.7" - -"@safe-global/safe-ethers-lib@^1.9.2": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@safe-global/safe-ethers-lib/-/safe-ethers-lib-1.9.4.tgz#049989a302c6f2010c574cf3a834b0cfb9cf67c5" - integrity sha512-WhzcmNun0s0VxeVQKRqaapV0vEpdm76zZBR2Du+S+58u1r57OjZkOSL2Gru0tdwkt3FIZZtE3OhDu09M70pVkA== - dependencies: - "@safe-global/safe-core-sdk-types" "^1.9.2" - "@safe-global/safe-core-sdk-utils" "^1.7.4" - ethers "5.7.2" - -"@safe-global/safe-service-client@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@safe-global/safe-service-client/-/safe-service-client-2.0.2.tgz#85e00017cb7f63d4cc9c9bf9702bd9cb7b27e62e" - integrity sha512-UFmA53EMRU++2mzo547+tCWaw2BknpbuMDjR786pPgm5dhB4ADattTdV7pYqYBMWn4uGoGgb2kaImEq097bATQ== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@safe-global/safe-core-sdk-types" "^1.9.2" - node-fetch "^2.6.6" - -"@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== - -"@scure/bip32@1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" - integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== - dependencies: - "@noble/hashes" "~1.2.0" - "@noble/secp256k1" "~1.7.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" - integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== - dependencies: - "@noble/hashes" "~1.2.0" - "@scure/base" "~1.1.0" - -"@sentry/core@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" - 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" - -"@sentry/hub@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" - integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== - dependencies: - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/minimal@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" - 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" - -"@sentry/node@^5.18.1": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" - 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" - -"@sentry/tracing@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" - 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" - -"@sentry/types@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" - integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== - -"@sentry/utils@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" - integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== - dependencies: - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^7.1.0": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" - integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@skalenetwork/etherbase-interfaces@^0.0.1-develop.20": - version "0.0.1-develop.20" - resolved "https://registry.yarnpkg.com/@skalenetwork/etherbase-interfaces/-/etherbase-interfaces-0.0.1-develop.20.tgz#33f61e18d695fd47063aa39dce4df335d26b9528" - integrity sha512-j3xnuQtOtjvjAoUMJgSUFxRa9/Egkg1RyA8r6PjcEb33VksE4LWLBy0PNFUFehLZv48595JROTcViGeXXwg5HQ== - -"@skalenetwork/ima-interfaces@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@skalenetwork/ima-interfaces/-/ima-interfaces-2.0.0.tgz#93cb73a5200f7d9753a44c1be3e15156e7ceaf9c" - integrity sha512-Kqm45GHQl56H4pqdWHIcTUfFrE60LAUKI3j2CecebN0T9rKa0DDokvE42VDa3PfK2z6XIJxh7SkF+i6NsLbpjA== - dependencies: - "@skalenetwork/skale-manager-interfaces" "^0.1.2" - -"@skalenetwork/skale-manager-interfaces@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-2.0.0.tgz#afb63131e5c498cfa69219567f9f52b85f0856c9" - integrity sha512-Pge3p4vpeNaXHjwntX+8b38NEcT81a67I32bbnU+l1uSo4kmyXd0VblHMO84H1Azr9TzF3ZmNCG+GI2yntSx2w== - -"@skalenetwork/skale-manager-interfaces@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-0.1.2.tgz#88e543c8cc298cd0cc9559892d746d2d74786da8" - integrity sha512-gapSQJahwWMlTB/xp/kMzB6k+9+Skx/N0fvEloiW4CUrkGkSa8+fj16YmUXX45p1hOc45W+JydiJPNgZtx32Dg== - -"@skalenetwork/upgrade-tools@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@skalenetwork/upgrade-tools/-/upgrade-tools-2.0.2.tgz#533a2d43d43706fc1898e003523464cee49ec11e" - integrity sha512-by5I3TM7RBi4G8FsicwxQE13rqx+XbPYf75x+CJnTELAFxg5UqMaPArG+YlHT2kBjl6O5OsESkCRtwbPcbIjsg== - dependencies: - "@openzeppelin/contracts-upgradeable" "^4.4.2" - "@safe-global/safe-core-sdk" "^3.3.2" - "@safe-global/safe-core-sdk-types" "^1.9.0" - "@safe-global/safe-ethers-lib" "^1.9.2" - "@safe-global/safe-service-client" "^2.0.0" - axios "^0.27.2" - ethereumjs-util "^7.1.4" - -"@smithy/types@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.0.2.tgz#49d42724c909e845bfd80a2e195740614ce497f3" - integrity sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw== - dependencies: - tslib "^2.5.0" - -"@solidity-parser/parser@^0.13.2": - version "0.13.2" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.13.2.tgz#b6c71d8ca0b382d90a7bbed241f9bc110af65cbe" - integrity sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@solidity-parser/parser@^0.16.0": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" - integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@trufflesuite/bigint-buffer@1.1.10": - version "1.1.10" - resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz#a1d9ca22d3cad1a138b78baaf15543637a3e1692" - integrity sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw== - dependencies: - node-gyp-build "4.4.0" - -"@trufflesuite/bigint-buffer@1.1.9": - version "1.1.9" - resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.9.tgz#e2604d76e1e4747b74376d68f1312f9944d0d75d" - integrity sha512-bdM5cEGCOhDSwminryHJbRmXc1x7dPKg6Pqns3qyTwFlxsqUgxE29lsERS3PlIW1HTjoIGMUqsk1zQQwST1Yxw== - dependencies: - node-gyp-build "4.3.0" - -"@trufflesuite/uws-js-unofficial@20.30.0-unofficial.0": - version "20.30.0-unofficial.0" - resolved "https://registry.yarnpkg.com/@trufflesuite/uws-js-unofficial/-/uws-js-unofficial-20.30.0-unofficial.0.tgz#2fbc2f8ef7e82fbeea6abaf7e8a9d42a02b479d3" - integrity sha512-r5X0aOQcuT6pLwTRLD+mPnAM/nlKtvIK4Z+My++A8tTOR0qTjNRx8UB8jzRj3D+p9PMAp5LnpCUUGmz7/TppwA== - dependencies: - ws "8.13.0" - optionalDependencies: - bufferutil "4.0.7" - utf-8-validate "6.0.3" - -"@typechain/ethers-v5@^10.0.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz#50241e6957683281ecfa03fb5a6724d8a3ce2391" - integrity sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - -"@typechain/ethers-v5@^11.1.1": - version "11.1.1" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-11.1.1.tgz#23a358135a302140cf89a186592464dd6bbf1f98" - integrity sha512-D9WyUrCJ4Z5Gg8T00HWLpuqn1CqSDXlCiUOOpLaWoCbnZrE2jSIOUwR9blBZNo6LE5058e3niVu6xk205Et7tg== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - -"@typechain/hardhat@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-7.0.0.tgz#ffa7465328150e793007fee616ae7b76ed20784d" - integrity sha512-XB79i5ewg9Met7gMVGfgVkmypicbnI25T5clJBEooMoW2161p4zvKFpoS2O+lBppQyMrPIZkdvl2M3LMDayVcA== - dependencies: - fs-extra "^9.1.0" - -"@types/abstract-leveldown@*": - version "7.2.1" - resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-7.2.1.tgz#bb16403c17754b0c4d5772d71d03b924a03d4c80" - integrity sha512-YK8irIC+eMrrmtGx0H4ISn9GgzLd9dojZWJaMbjp1YHLl2VqqNFBNrL5Q3KjGf4VE3sf/4hmq6EhQZ7kZp1NoQ== - -"@types/bn.js@*": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - -"@types/bn.js@^4.11.3": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - -"@types/chai-almost@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/chai-almost/-/chai-almost-1.0.1.tgz#e8a2de03b53c22e9a2dd2c85ef98bde5f19b685c" - integrity sha512-UwJTbGAP8Jc84JwpSeCEiE50LBvE7MD4pWYsWdwgZG/umPjUlAYCEMK4WnzbEQO/08HH2jDJ+Ikm9CPzHWdGGQ== - dependencies: - "@types/chai" "*" - -"@types/chai-as-promised@^7.1.3": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.4.tgz#caf64e76fb056b8c8ced4b761ed499272b737601" - integrity sha512-1y3L1cHePcIm5vXkh1DSGf/zQq5n5xDKG1fpCvf18+uOkpce0Z1ozNFPkyWsVswK7ntN1sZBw3oU6gmN+pDUcA== - dependencies: - "@types/chai" "*" - -"@types/chai@*", "@types/chai@^4.2.12": - version "4.2.22" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.22.tgz#47020d7e4cf19194d43b5202f35f75bd2ad35ce7" - integrity sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ== - -"@types/elliptic@^6.4.14": - version "6.4.14" - resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.14.tgz#7bbaad60567a588c1f08b10893453e6b9b4de48e" - integrity sha512-z4OBcDAU0GVwDTuwJzQCiL6188QvZMkvoERgcVjq0/mPM8jCfdwZ3x5zQEVoL9WCAru3aG5wl3Z5Ww5wBWn7ZQ== - dependencies: - "@types/bn.js" "*" - -"@types/glob@^7.1.1": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672" - integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/json-schema@^7.0.12": - version "7.0.12" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" - integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== - -"@types/level-errors@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/level-errors/-/level-errors-3.0.0.tgz#15c1f4915a5ef763b51651b15e90f6dc081b96a8" - integrity sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ== - -"@types/levelup@^4.3.0": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@types/levelup/-/levelup-4.3.3.tgz#4dc2b77db079b1cf855562ad52321aa4241b8ef4" - integrity sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA== - dependencies: - "@types/abstract-leveldown" "*" - "@types/level-errors" "*" - "@types/node" "*" - -"@types/lru-cache@5.1.1", "@types/lru-cache@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" - integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== - -"@types/minimatch@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== - -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - -"@types/mocha@^9.1.0": - version "9.1.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" - integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== - -"@types/node-fetch@^2.6.1": - version "2.6.4" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.4.tgz#1bc3a26de814f6bf466b25aeb1473fa1afe6a660" - integrity sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "20.4.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69" - integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg== - -"@types/node@11.11.6": - version "11.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== - -"@types/node@^12.12.6": - version "12.20.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.27.tgz#4141fcad57c332a120591de883e26fe4bb14aaea" - integrity sha512-qZdePUDSLAZRXXV234bLBEUM0nAQjoxbcSwp1rqSMUe1rZ47mwU6OjciR/JvF1Oo8mc0ys6GE0ks0HGgqAZoGg== - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== - dependencies: - "@types/node" "*" - -"@types/prettier@^2.1.1": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.0.tgz#900b13362610ccd3570fb6eefb911a6732973d00" - integrity sha512-WHRsy5nMpjXfU9B0LqOqPT06EI2+8Xv5NERy0pLxJLbU98q7uhcGogQzfX+rXpU7S5mgHsLxHrLCufZcV/P8TQ== - -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" - -"@types/resolve@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" - integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== - dependencies: - "@types/node" "*" - -"@types/seedrandom@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.1.tgz#1254750a4fec4aff2ebec088ccd0bb02e91fedb4" - integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw== - -"@types/semver@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@types/sinon-chai@^3.2.5": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48" - integrity sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "10.0.5" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.5.tgz#01e7037ac0c6c5c54c1606463421ad5c6afc43e7" - integrity sha512-BrAUy0yq3n84XOykYGvGbDir9nBIYwQm2NdBNQT0DbtDLqh/5nMUsjz5XfwrefFNLPE9B6g8yLOZREpvw0J40A== - dependencies: - "@sinonjs/fake-timers" "^7.1.0" - -"@typescript-eslint/eslint-plugin@^6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz#41b79923fee46a745a3a50cba1c33c622aa3c79a" - integrity sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.2.1" - "@typescript-eslint/type-utils" "6.2.1" - "@typescript-eslint/utils" "6.2.1" - "@typescript-eslint/visitor-keys" "6.2.1" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.4" - natural-compare "^1.4.0" - natural-compare-lite "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/parser@^6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.2.1.tgz#e18a31eea1cca8841a565f1701960c8123ed07f9" - integrity sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg== - dependencies: - "@typescript-eslint/scope-manager" "6.2.1" - "@typescript-eslint/types" "6.2.1" - "@typescript-eslint/typescript-estree" "6.2.1" - "@typescript-eslint/visitor-keys" "6.2.1" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz#b6f43a867b84e5671fe531f2b762e0b68f7cf0c4" - integrity sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q== - dependencies: - "@typescript-eslint/types" "6.2.1" - "@typescript-eslint/visitor-keys" "6.2.1" - -"@typescript-eslint/type-utils@6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz#8eb8a2cccdf39cd7cf93e02bd2c3782dc90b0525" - integrity sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ== - dependencies: - "@typescript-eslint/typescript-estree" "6.2.1" - "@typescript-eslint/utils" "6.2.1" - debug "^4.3.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/types@6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.2.1.tgz#7fcdeceb503aab601274bf5e210207050d88c8ab" - integrity sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ== - -"@typescript-eslint/typescript-estree@6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz#2af6e90c1e91cb725a5fe1682841a3f74549389e" - integrity sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q== - dependencies: - "@typescript-eslint/types" "6.2.1" - "@typescript-eslint/visitor-keys" "6.2.1" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/utils@6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.2.1.tgz#2aa4279ec13053d05615bcbde2398e1e8f08c334" - integrity sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.2.1" - "@typescript-eslint/types" "6.2.1" - "@typescript-eslint/typescript-estree" "6.2.1" - semver "^7.5.4" - -"@typescript-eslint/visitor-keys@6.2.1": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz#442e7c09fe94b715a54ebe30e967987c3c41fbf4" - integrity sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA== - dependencies: - "@typescript-eslint/types" "6.2.1" - eslint-visitor-keys "^3.4.1" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abbrev@1.0.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -abortcontroller-polyfill@^1.7.3: - version "1.7.5" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" - integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== - -abstract-level@1.0.3, abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== - dependencies: - buffer "^6.0.3" - catering "^2.1.0" - is-buffer "^2.0.5" - level-supports "^4.0.0" - level-transcoder "^1.0.1" - module-error "^1.0.1" - queue-microtask "^1.2.3" - -abstract-leveldown@7.2.0, abstract-leveldown@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#08d19d4e26fb5be426f7a57004851b39e1795a2e" - integrity sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ== - dependencies: - buffer "^6.0.3" - catering "^2.0.0" - is-buffer "^2.0.5" - level-concat-iterator "^3.0.0" - level-supports "^2.0.1" - queue-microtask "^1.2.3" - -abstract-leveldown@^6.2.1: - version "6.3.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" - 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" - -abstract-leveldown@~6.2.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" - 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" - -acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^6.0.7: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - -address@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" - integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== - -adm-zip@^0.4.16: - version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" - integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.6.1, ajv@^6.9.1: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - 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" - -ajv@^8.0.1: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -amazon-cognito-identity-js@^6.0.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.1.tgz#d9a4c1a92f4b059330df8ea075f65106d2605409" - integrity sha512-PxBdufgS8uZShrcIFAsRjmqNXsh/4fXOWUGQOUhKLHWWK1pcp/y+VeFF48avXIWefM8XwsT3JlN6m9J2eHt4LA== - dependencies: - "@aws-crypto/sha256-js" "1.2.2" - buffer "4.9.2" - fast-base64-decode "^1.0.0" - isomorphic-unfetch "^3.0.0" - js-cookie "^2.2.1" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - -ansi-colors@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" - integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== - -ansi-colors@4.1.1, ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -antlr4@4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" - integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== - -antlr4ts@^0.5.0-alpha.4: - version "0.5.0-alpha.4" - resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" - integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== - -anymatch@~3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1, array-back@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.reduce@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" - integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" - -arraybuffer.prototype.slice@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" - integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -ast-parents@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" - integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -async-eventemitter@0.2.4, async-eventemitter@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" - integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== - dependencies: - async "^2.4.0" - -async-retry@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" - integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== - dependencies: - retry "0.13.1" - -async@1.x: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= - -async@^2.4.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" - integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== - -axios@^0.21.2, axios@^0.21.4: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - -axios@^0.27.2: - version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== - dependencies: - follow-redirects "^1.14.9" - form-data "^4.0.0" - -axios@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" - integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.0.2, base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -bigint-crypto-utils@^3.0.23: - version "3.3.0" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" - integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== - -bignumber.js@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" - integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bip39@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" - integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== - dependencies: - "@types/node" "11.11.6" - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - -blakejs@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" - integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= - -bn.js@^4.0.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.1, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.0.1, brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -browser-level@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" - integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.1" - module-error "^1.0.2" - run-parallel-limit "^1.1.0" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - 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" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - -buffer-xor@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" - integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== - dependencies: - safe-buffer "^5.1.1" - -buffer@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -buffer@^5.5.0, buffer@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bufferutil@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" - integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A== - dependencies: - node-gyp-build "^4.3.0" - -bufferutil@4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== - dependencies: - node-gyp-build "^4.3.0" - -bufferutil@^4.0.1: - version "4.0.4" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.4.tgz#ab81373d313a6ead0d734e98c448c722734ae7bb" - integrity sha512-VNxjXUCrF3LvbLgwfkTb5LsFvk6pGIn7OBb9x+3o+iJ6mKw0JTUp4chBFc88hi1aspeZGeZG9jAIbpFYPQSLZw== - dependencies: - node-gyp-build "^4.2.0" - -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -case@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" - integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - -catering@^2.0.0, catering@^2.1.0, catering@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" - integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== - -cbor@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.0.0.tgz#51657d26a99a6a1866f8c3258e948576eb17d709" - integrity sha512-nMmaLWbj7+bC6MsApKRIig8h+yjgNLhPLXaCelq5+C7mpWsHgIcseZSdvgexSY5uE1Q3m2uPvIDZwSdxdo7qig== - dependencies: - nofilter "^3.0.2" - -cbor@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" - integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== - dependencies: - nofilter "^3.1.0" - -chai-almost@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chai-almost/-/chai-almost-1.0.1.tgz#43d026cf3be79a1cd513cf15af840a81243a4b60" - integrity sha1-Q9AmzzvnmhzVE88Vr4QKgSQ6S2A= - dependencies: - deep-eql "^2.0.2" - type-detect "^4.0.3" - -chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" - integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - dependencies: - check-error "^1.0.2" - -chai@^4.2.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - 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" - -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - 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" - -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" - 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" - optionalDependencies: - fsevents "~2.1.1" - -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - 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" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^3.4.0: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - 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" - optionalDependencies: - fsevents "~2.3.2" - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -classic-level@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" - integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.0" - module-error "^1.0.1" - napi-macros "^2.2.2" - node-gyp-build "^4.3.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" - integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -command-line-args@^5.1.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.1.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" - integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== - dependencies: - array-back "^4.0.2" - chalk "^2.4.2" - table-layout "^1.0.2" - typical "^5.2.0" - -commander@2.18.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" - integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -commander@^8.1.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -compare-versions@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.0.0.tgz#a3edb527e4487bfab9a8b62ffe70cebc9b87675b" - integrity sha512-s2MzYxfRsE9f/ow8hjn7ysa7pod1xhHdQMsgiJtKx6XSNf4x2N1KG4fjrkUmXcP/e9Y2ZX4zB6sHIso0Lm6evQ== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -cookie@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== - -core-js-pure@^3.0.1: - version "3.32.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.32.0.tgz#5d79f85da7a4373e9a06494ccbef995a4c639f8b" - integrity sha512-qsev1H+dTNYpDUEURRuOXMvpdtAnNEvQWS/FMJ2Vb5AY8ZP4rAPQldkE27joykZPJTe0+IVgHZYh1P5Xu1/i1g== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - -cosmiconfig@^5.0.7: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - 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" - -crc-32@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" - integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - 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" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - 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" - -cross-fetch@^3.1.4: - version "3.1.8" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" - integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== - dependencies: - node-fetch "^2.6.12" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - 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" - -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - -death@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" - integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= - -debug@3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@4, debug@^4.0.1, debug@^4.1.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@4.3.4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^2.2.0, debug@^2.6.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-eql@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-2.0.2.tgz#b1bac06e56f0a76777686d50c9feb75c2ed7679a" - integrity sha1-sbrAblbwp2d3aG1Qyf63XC7XZ5o= - dependencies: - type-detect "^3.0.0" - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deferred-leveldown@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" - integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== - dependencies: - abstract-leveldown "~6.2.1" - inherits "^2.0.3" - -define-properties@^1.1.2, define-properties@^1.1.4, define-properties@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -detect-port@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" - integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== - dependencies: - address "^1.0.1" - debug "^2.6.0" - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -difflib@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" - integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w== - dependencies: - heap ">= 0.2.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dotenv@^16.0.0: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - 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" - -emittery@0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.0.tgz#bb373c660a9d421bb44706ec4967ed50c02a8026" - integrity sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encoding-down@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" - integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== - dependencies: - abstract-leveldown "^6.2.1" - inherits "^2.0.3" - level-codec "^9.0.0" - level-errors "^2.0.0" - -enquirer@^2.3.0: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -errno@~0.1.1: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.18.5: - version "1.18.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.6.tgz#2c44e3ea7a6255039164d26559777a6d978cb456" - integrity sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ== - dependencies: - 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-string "^1.0.7" - 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" - -es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: - version "1.22.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" - integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.1" - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.2.1" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.10" - is-weakref "^1.0.2" - object-inspect "^1.12.3" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" - safe-array-concat "^1.0.0" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.7" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.10" - -es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.53" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" - integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" - -es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-promise@^4.2.8: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-symbol@^3.1.1, es6-symbol@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@1.8.x: - version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= - dependencies: - esprima "^2.7.1" - estraverse "^1.9.1" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.2.0" - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^1.3.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz#8c2095440eca8c933bedcadf16fefa44dbe9ba5f" - integrity sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw== - -eslint@^5.6.0: - version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== - dependencies: - "@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" - -eslint@^8.46.0: - version "8.46.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.46.0.tgz#a06a0ff6974e53e643acc42d1dcf2e7f797b3552" - integrity sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.1" - "@eslint/js" "^8.46.0" - "@humanwhocodes/config-array" "^0.11.10" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.2" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esprima@2.7.x, esprima@^2.7.1: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.1.0, esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== - dependencies: - js-sha3 "^0.8.0" - -ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - 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" - -ethereum-cryptography@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" - integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== - dependencies: - "@noble/hashes" "1.2.0" - "@noble/secp256k1" "1.7.1" - "@scure/bip32" "1.1.5" - "@scure/bip39" "1.1.1" - -ethereum-waffle@^4.0.10: - version "4.0.10" - resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-4.0.10.tgz#f1ef1564c0155236f1a66c6eae362a5d67c9f64c" - integrity sha512-iw9z1otq7qNkGDNcMoeNeLIATF9yKl1M8AIeu42ElfNBplq0e+5PeasQmm8ybY/elkZ1XyRO0JBQxQdVRb8bqQ== - dependencies: - "@ethereum-waffle/chai" "4.0.10" - "@ethereum-waffle/compiler" "4.0.3" - "@ethereum-waffle/mock-contract" "4.0.4" - "@ethereum-waffle/provider" "4.0.5" - solc "0.8.15" - typechain "^8.0.0" - -ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-util@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" - 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" - -ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - 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" - -ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.1.tgz#236ef435f46820f0c420a708c0559b5897952069" - integrity sha512-1CGBmCp3m8IMGHhAJF/icH8qjCJrfQtaZ9KW+cAVV8kyN5Lc1IRq3KjV77ILOutrCwiyf5y2gMyCrAUMoCf2Ag== - dependencies: - "@types/bn.js" "^5.1.0" - bn.js "^5.1.2" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.4" - -ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.3, ethereumjs-util@^7.1.5: - version "7.1.5" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" - integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== - 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" - -ethereumjs-util@^7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" - integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== - 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" - -ethers@5.7.2, ethers@^5.7.1, ethers@^5.7.2: - version "5.7.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" - integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== - dependencies: - "@ethersproject/abi" "5.7.0" - "@ethersproject/abstract-provider" "5.7.0" - "@ethersproject/abstract-signer" "5.7.0" - "@ethersproject/address" "5.7.0" - "@ethersproject/base64" "5.7.0" - "@ethersproject/basex" "5.7.0" - "@ethersproject/bignumber" "5.7.0" - "@ethersproject/bytes" "5.7.0" - "@ethersproject/constants" "5.7.0" - "@ethersproject/contracts" "5.7.0" - "@ethersproject/hash" "5.7.0" - "@ethersproject/hdnode" "5.7.0" - "@ethersproject/json-wallets" "5.7.0" - "@ethersproject/keccak256" "5.7.0" - "@ethersproject/logger" "5.7.0" - "@ethersproject/networks" "5.7.1" - "@ethersproject/pbkdf2" "5.7.0" - "@ethersproject/properties" "5.7.0" - "@ethersproject/providers" "5.7.2" - "@ethersproject/random" "5.7.0" - "@ethersproject/rlp" "5.7.0" - "@ethersproject/sha2" "5.7.0" - "@ethersproject/signing-key" "5.7.0" - "@ethersproject/solidity" "5.7.0" - "@ethersproject/strings" "5.7.0" - "@ethersproject/transactions" "5.7.0" - "@ethersproject/units" "5.7.0" - "@ethersproject/wallet" "5.7.0" - "@ethersproject/web" "5.7.1" - "@ethersproject/wordlists" "5.7.0" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -eventemitter3@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" - integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== - -evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -exit-on-epipe@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" - integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== - -ext@^1.1.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" - integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== - dependencies: - type "^2.5.0" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - -fast-base64-decode@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418" - integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-glob@^3.0.3: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - 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" - -fast-glob@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - 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" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - -find-up@3.0.0, find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flat@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" - integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== - dependencies: - is-buffer "~2.0.3" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -follow-redirects@^1.12.1, follow-redirects@^1.14.0: - version "1.14.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379" - integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g== - -follow-redirects@^1.14.9, follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - 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" - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -functions-have-names@^1.2.2, functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -ganache@7.4.3: - version "7.4.3" - resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.4.3.tgz#e995f1250697264efbb34d4241c374a2b0271415" - integrity sha512-RpEDUiCkqbouyE7+NMXG26ynZ+7sGiODU84Kz+FVoXUnQ4qQM4M8wif3Y4qUCt+D/eM1RVeGq0my62FPD6Y1KA== - dependencies: - "@trufflesuite/bigint-buffer" "1.1.10" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "5.1.1" - "@types/seedrandom" "3.0.1" - emittery "0.10.0" - keccak "3.0.2" - leveldown "6.1.0" - secp256k1 "4.0.3" - optionalDependencies: - bufferutil "4.0.5" - utf-8-validate "5.0.7" - -ganache@7.9.2: - version "7.9.2" - resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.9.2.tgz#77f506ad2735dd9109696ffa1834a9dd2f806449" - integrity sha512-7gsVVDpO9AhrFyDMWWl7SpMsPpqGcnAzjxz3k32LheIPNd64p2XsY9GYRdhWmKuryb60W1iaWPZWDkFKlbRWHA== - dependencies: - "@trufflesuite/bigint-buffer" "1.1.10" - "@trufflesuite/uws-js-unofficial" "20.30.0-unofficial.0" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "5.1.1" - "@types/seedrandom" "3.0.1" - abstract-level "1.0.3" - abstract-leveldown "7.2.0" - async-eventemitter "0.2.4" - emittery "0.10.0" - keccak "3.0.2" - leveldown "6.1.0" - secp256k1 "4.0.3" - optionalDependencies: - bufferutil "4.0.5" - utf-8-validate "5.0.7" - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - -ghost-testrpc@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" - integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== - dependencies: - chalk "^2.4.2" - node-emoji "^1.10.0" - -glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - 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" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - 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" - -glob@7.2.0, glob@^7.0.0, glob@^7.1.2, glob@^7.1.3: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - 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" - -glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-modules@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -globals@^11.7.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@^10.0.1: - version "10.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" - 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" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handlebars@^4.0.1: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - 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" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -"hardhat@2.11.0 - 2.16.1": - version "2.16.1" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.16.1.tgz#fd2288ce44f6846a70ba332b3d8158522447262a" - integrity sha512-QpBjGXFhhSYoYBGEHyoau/A63crZOP+i3GbNxzLGkL6IklzT+piN14+wGnINNCg5BLSKisQI/RAySPzaWRcx/g== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-blockchain" "7.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-evm" "2.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-statemanager" "2.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - "@nomicfoundation/ethereumjs-vm" "7.0.1" - "@nomicfoundation/solidity-analyzer" "^0.1.0" - "@sentry/node" "^5.18.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 "^1.0.3" - ethereumjs-abi "^0.6.8" - find-up "^2.1.0" - fp-ts "1.19.3" - fs-extra "^7.0.1" - glob "7.2.0" - immutable "^4.0.0-rc.12" - io-ts "1.10.4" - keccak "^3.0.2" - lodash "^4.17.11" - mnemonist "^0.38.0" - mocha "^10.0.0" - p-map "^4.0.0" - raw-body "^2.4.1" - resolve "1.17.0" - semver "^6.3.0" - solc "0.7.3" - source-map-support "^0.5.13" - stacktrace-parser "^0.1.10" - tsort "0.0.1" - undici "^5.14.0" - uuid "^8.3.2" - ws "^7.4.6" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.0, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -"heap@>= 0.2.0": - version "0.2.7" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" - integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hosted-git-info@^2.6.0: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -http-errors@1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-https@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" - integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -ignore@^5.2.0, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -immediate@^3.2.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" - integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== - -immediate@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg== - -immutable@^4.0.0-rc.12: - version "4.0.0-rc.15" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0-rc.15.tgz#c30056f05eaaf5650fd15230586688fdd15c54bc" - integrity sha512-v8+A3sNyaieoP9dHegl3tEYnIZa7vqNiSv0U6D7YddiZi34VjKy4GsIxrRHj2d8+CS3MeiVja5QyNe4JO/aEXA== - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.5: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -inquirer@^6.2.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - 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" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== - dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" - side-channel "^1.0.4" - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== - dependencies: - fp-ts "^1.0.0" - -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^2.0.5, is-buffer@~2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.2.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19" - integrity sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -is-glob@^4.0.0, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.2.tgz#859fc2e731e58c902f99fcabccb75a7dd07d29d8" - integrity sha512-ZZTOjRcDjuAAAv2cTBQP/lL59ZTArx77+7UzHdWW/XB1mrfp7DEaVpKmZ0XIzx+M7AxfhKcqV+nMetUQmFifwg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-typed-array@^1.1.3, is-typed-array@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" - 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" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-url@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" - integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -isarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isomorphic-unfetch@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" - integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== - dependencies: - node-fetch "^2.6.1" - unfetch "^4.2.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - -js-cookie@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" - integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== - -js-sdsl@^4.1.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" - integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== - -js-sha3@0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= - -js-sha3@0.8.0, js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - -json-bigint@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" - integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== - dependencies: - bignumber.js "^9.0.0" - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonschema@^1.2.4: - version "1.4.0" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2" - integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - -keccak@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" - integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -keccak@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" - integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -keccak@^3.0.0, keccak@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" - integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - -level-codec@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" - integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== - dependencies: - buffer "^5.6.0" - -level-concat-iterator@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz#5235b1f744bc34847ed65a50548aa88d22e881cf" - integrity sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ== - dependencies: - catering "^2.1.0" - -level-concat-iterator@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" - integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== - -level-errors@^2.0.0, level-errors@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" - integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== - dependencies: - errno "~0.1.1" - -level-iterator-stream@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" - integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== - dependencies: - inherits "^2.0.4" - readable-stream "^3.4.0" - xtend "^4.0.2" - -level-mem@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-5.0.1.tgz#c345126b74f5b8aa376dc77d36813a177ef8251d" - integrity sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg== - dependencies: - level-packager "^5.0.3" - memdown "^5.0.0" - -level-packager@^5.0.3: - version "5.1.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" - integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== - dependencies: - encoding-down "^6.3.0" - levelup "^4.3.2" - -level-supports@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-2.1.0.tgz#9af908d853597ecd592293b2fad124375be79c5f" - integrity sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA== - -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - -level-supports@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" - integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== - dependencies: - xtend "^4.0.2" - -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - -level-ws@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" - integrity sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA== - dependencies: - inherits "^2.0.3" - readable-stream "^3.1.0" - xtend "^4.0.1" - -level@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" - integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== - dependencies: - browser-level "^1.0.1" - classic-level "^1.2.0" - -leveldown@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-6.1.0.tgz#7ab1297706f70c657d1a72b31b40323aa612b9ee" - integrity sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w== - dependencies: - abstract-leveldown "^7.2.0" - napi-macros "~2.0.0" - node-gyp-build "^4.3.0" - -levelup@^4.3.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" - 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" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - -lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= - -ltgt@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" - integrity sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -mcl-wasm@^0.7.1: - version "0.7.9" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" - integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -memdown@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" - 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" - -memory-level@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" - integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== - dependencies: - abstract-level "^1.0.0" - functional-red-black-tree "^1.0.1" - module-error "^1.0.1" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -merkle-patricia-tree@^4.2.2, merkle-patricia-tree@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz#ff988d045e2bf3dfa2239f7fabe2d59618d57413" - integrity sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w== - dependencies: - "@types/levelup" "^4.3.0" - ethereumjs-util "^7.1.4" - level-mem "^5.0.1" - level-ws "^2.0.0" - readable-stream "^3.6.0" - semaphore-async-await "^1.5.1" - -micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.49.0: - version "1.49.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" - integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.32" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" - integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== - dependencies: - mime-db "1.49.0" - -mime-types@~2.1.19: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^3.0.5, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minimist@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp@0.5.5, mkdirp@0.5.x, mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mnemonist@^0.38.0: - version "0.38.4" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.4.tgz#5d2f2dc4386aef78bfadeea60ce704dcf0ef8f3d" - integrity sha512-mflgW0gEWmVLbDDE2gJbOh3+RltTN7CgV9jV25qyCnyLN9FtoltWr7ZtAEDeD9u8W4oFAoolR6fBWieXdn3u8Q== - dependencies: - obliterator "^1.6.1" - -mocha@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.2.tgz#8e40d198acf91a52ace122cd7599c9ab857b29e6" - integrity sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA== - dependencies: - 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" - -mocha@^10.0.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -module-error@^1.0.1, module-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - -napi-macros@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" - integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== - -napi-macros@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" - integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-emoji@^1.10.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" - integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== - dependencies: - lodash "^4.17.21" - -node-environment-flags@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" - integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.5" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" - integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.12, node-fetch@^2.6.6, node-fetch@^2.6.7: - version "2.6.12" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" - integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" - integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== - -node-gyp-build@4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" - integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== - -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== - -nofilter@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.0.3.tgz#3ff3b142efdccb403434ccae4a0c2c835cb9b522" - integrity sha512-TN/MCrQmXQk5DyUJ8TGUq1Il8rv4fTsjddLmMopV006QP8DMkglmGgYfQKD5620vXLRXfr8iGI6ZZ4/ZWld2cQ== - -nofilter@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" - integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== - -nopt@3.x: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= - dependencies: - abbrev "1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== - -object-inspect@^1.12.3: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - 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" - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - 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" - -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.6" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz#5e5c384dd209fa4efffead39e3a0512770ccc312" - integrity sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ== - dependencies: - array.prototype.reduce "^1.0.5" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.21.2" - safe-array-concat "^1.0.0" - -obliterator@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-1.6.1.tgz#dea03e8ab821f6c4d96a299e17aef6a3af994ef3" - integrity sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig== - -oboe@2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" - integrity sha1-VVQoTFQ6ImbXo48X4HOCH73jk80= - dependencies: - http-https "^1.0.0" - -once@1.x, once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -optionator@^0.8.1, optionator@^0.8.2: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - 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" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -path-browserify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -pbkdf2@^3.0.17, pbkdf2@^3.0.9: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - 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" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prettier@^1.14.3: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -prettier@^2.1.2: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" - integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== - -prettier@^2.3.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -printj@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -proper-lockfile@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" - integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== - dependencies: - graceful-fs "^4.2.4" - retry "^0.12.0" - signal-exit "^3.0.2" - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== - -psl@^1.1.28: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -qs@^6.11.0: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - -queue-microtask@^1.2.2, queue-microtask@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randombytes@^2.0.1, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -raw-body@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" - integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== - dependencies: - bytes "3.1.0" - http-errors "1.7.3" - iconv-lite "0.4.24" - unpipe "1.0.0" - -readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" - integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== - dependencies: - picomatch "^2.0.4" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -recursive-readdir@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" - integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== - dependencies: - minimatch "3.0.4" - -reduce-flatten@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - -regexp.prototype.flags@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" - integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - functions-have-names "^1.2.3" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -request@^2.85.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - 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" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.0, require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@1.1.x: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.1.6, resolve@^1.8.1: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -retry@0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.2.8: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@2.2.6, rlp@^2.2.3: - version "2.2.6" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" - integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg== - dependencies: - bn.js "^4.11.1" - -rlp@^2.2.4: - version "2.2.7" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" - integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== - dependencies: - bn.js "^5.2.0" - -run-async@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" - integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== - dependencies: - queue-microtask "^1.2.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -rxjs@^6.4.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -safe-array-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" - integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sc-istanbul@^0.4.5: - version "0.4.6" - resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" - 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" - -scrypt-js@3.0.1, scrypt-js@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@4.0.3, secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== - dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -seedrandom@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" - integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== - -semaphore-async-await@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa" - integrity sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg== - -semver@^5.5.0, semver@^5.5.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^5.7.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.3.4: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shelljs@^0.8.3: - version "0.8.4" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" - integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.4.tgz#366a4684d175b9cab2081e3681fda3747b6c51d7" - integrity sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - 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" - -solc@0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.15.tgz#d274dca4d5a8b7d3c9295d4cbdc9291ee1c52152" - integrity sha512-Riv0GNHNk/SddN/JyEuFKwbcWcEeho15iyupTSHw5Np6WuXA5D8kEHbyzDHi6sqmvLzu2l+8b1YmL8Ytple+8w== - dependencies: - command-exists "^1.2.8" - commander "^8.1.0" - follow-redirects "^1.12.1" - js-sha3 "0.8.0" - memorystream "^0.3.1" - semver "^5.5.0" - tmp "0.0.33" - -solhint@3.3.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.6.tgz#abe9af185a9a7defefba480047b3e42cbe9a1210" - 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" - optionalDependencies: - prettier "^1.14.3" - -solidity-ast@^0.4.15: - version "0.4.49" - resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.49.tgz#ecba89d10c0067845b7848c3a3e8cc61a4fc5b82" - integrity sha512-Pr5sCAj1SFqzwFZw1HPKSq0PehlQNdM8GwKyAVYh2DOn7/cCK8LUKD1HeHnKtTgBW7hi9h4nnnan7hpAg5RhWQ== - -solidity-coverage@^0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.4.tgz#c57a21979f5e86859c5198de9fbae2d3bc6324a5" - integrity sha512-xeHOfBOjdMF6hWTbt42iH4x+7j1Atmrf5OldDPMxI+i/COdExUxszOswD9qqvcBTaLGiOrrpnh9UZjSpt4rBsg== - dependencies: - "@ethersproject/abi" "^5.0.9" - "@solidity-parser/parser" "^0.16.0" - chalk "^2.4.2" - death "^1.1.0" - detect-port "^1.3.0" - difflib "^0.2.4" - 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" - mocha "7.1.2" - 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.6" - -source-map-support@^0.5.13, source-map-support@^0.5.17: - version "0.5.20" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" - integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" - integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= - dependencies: - amdefine ">=0.0.4" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - 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" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - -"statuses@>= 1.5.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string-format@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" - integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== - -"string-width@^1.0.2 || 2", string-width@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.trim@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= - dependencies: - is-hex-prefixed "1.0.0" - -strip-json-comments@2.0.1, strip-json-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -strip-json-comments@3.1.1, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== - dependencies: - has-flag "^3.0.0" - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^3.1.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -table-layout@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - 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" - -table@^6.8.0: - version "6.8.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" - integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -tmp@0.0.33, tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - -ts-api-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" - integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== - -ts-command-line-args@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.2.1.tgz#fd6913e542099012c0ffb2496126a8f38305c7d6" - integrity sha512-mnK68QA86FYzQYTSA/rxIjT/8EpKsvQw9QkawPic8I8t0gjAOw3Oa509NIRoaY1FmH7hdrncMp7t7o+vYoceNQ== - dependencies: - chalk "^4.1.0" - command-line-args "^5.1.1" - command-line-usage "^6.1.0" - string-format "^2.0.0" - -ts-essentials@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" - integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== - -ts-essentials@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" - integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== - -ts-generator@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" - integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== - 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" - -ts-node@^8.10.2: - version "8.10.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" - integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - -tslib@^1.11.1, tslib@^1.9.0, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.3.1, tslib@^2.5.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" - integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y= - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - -tweetnacl-util@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.3, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-detect@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-3.0.0.tgz#46d0cc8553abb7b13a352b0d6dea2fd58f2d9b55" - integrity sha1-RtDMhVOrt7E6NSsNbeov1Y8tm1U= - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" - integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== - -typechain@^8.0.0, typechain@^8.3.1: - version "8.3.1" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.1.tgz#dccbc839b94877997536c356380eff7325395cfb" - integrity sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ== - dependencies: - "@types/prettier" "^2.1.1" - debug "^4.3.1" - fs-extra "^7.0.0" - glob "7.1.7" - js-sha3 "^0.8.0" - lodash "^4.17.15" - mkdirp "^1.0.4" - prettier "^2.3.1" - ts-command-line-args "^2.2.0" - ts-essentials "^7.0.1" - -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typescript@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== - -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - -uglify-js@^3.1.4: - version "3.14.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.2.tgz#d7dd6a46ca57214f54a2d0a43cad0f35db82ac99" - integrity sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - 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" - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -undici@^5.14.0: - version "5.22.1" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.22.1.tgz#877d512effef2ac8be65e695f3586922e1a57d7b" - integrity sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw== - dependencies: - busboy "^1.6.0" - -unfetch@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" - integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.1.tgz#26f90f615427eca1b9f4d6a28288c147e2302a32" - integrity sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA== - dependencies: - punycode "^1.4.1" - qs "^6.11.0" - -utf-8-validate@5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.7.tgz#c15a19a6af1f7ad9ec7ddc425747ca28c3644922" - integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q== - dependencies: - node-gyp-build "^4.3.0" - -utf-8-validate@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-6.0.3.tgz#7d8c936d854e86b24d1d655f138ee27d2636d777" - integrity sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA== - dependencies: - node-gyp-build "^4.3.0" - -utf-8-validate@^5.0.2: - version "5.0.6" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.6.tgz#e1b3e0a5cc8648a3b44c1799fbb170d1aaaffe80" - integrity sha512-hoY0gOf9EkCw+nimK21FVKHUIG1BMqSiRwxB/q3A9yKZOrOI99PP77BxmarDqWz6rG3vVYiBWfhG8z2Tl+7fZA== - dependencies: - node-gyp-build "^4.2.0" - -utf8@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -util@^0.12.5: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -web3-core-helpers@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.0.tgz#1016534c51a5df77ed4f94d1fcce31de4af37fad" - integrity sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g== - dependencies: - web3-eth-iban "1.10.0" - web3-utils "1.10.0" - -web3-core-method@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.0.tgz#82668197fa086e8cc8066742e35a9d72535e3412" - integrity sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA== - dependencies: - "@ethersproject/transactions" "^5.6.2" - web3-core-helpers "1.10.0" - web3-core-promievent "1.10.0" - web3-core-subscriptions "1.10.0" - web3-utils "1.10.0" - -web3-core-promievent@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.0.tgz#cbb5b3a76b888df45ed3a8d4d8d4f54ccb66a37b" - integrity sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg== - dependencies: - eventemitter3 "4.0.4" - -web3-core-requestmanager@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.0.tgz#4b34f6e05837e67c70ff6f6993652afc0d54c340" - integrity sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ== - dependencies: - util "^0.12.5" - web3-core-helpers "1.10.0" - web3-providers-http "1.10.0" - web3-providers-ipc "1.10.0" - web3-providers-ws "1.10.0" - -web3-core-subscriptions@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.0.tgz#b534592ee1611788fc0cb0b95963b9b9b6eacb7c" - integrity sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g== - dependencies: - eventemitter3 "4.0.4" - web3-core-helpers "1.10.0" - -web3-core@^1.8.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.0.tgz#9aa07c5deb478cf356c5d3b5b35afafa5fa8e633" - integrity sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ== - dependencies: - "@types/bn.js" "^5.1.1" - "@types/node" "^12.12.6" - bignumber.js "^9.0.0" - web3-core-helpers "1.10.0" - web3-core-method "1.10.0" - web3-core-requestmanager "1.10.0" - web3-utils "1.10.0" - -web3-eth-iban@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz#5a46646401965b0f09a4f58e7248c8a8cd22538a" - integrity sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg== - dependencies: - bn.js "^5.2.1" - web3-utils "1.10.0" - -web3-providers-http@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.0.tgz#864fa48675e7918c9a4374e5f664b32c09d0151b" - integrity sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA== - dependencies: - abortcontroller-polyfill "^1.7.3" - cross-fetch "^3.1.4" - es6-promise "^4.2.8" - web3-core-helpers "1.10.0" - -web3-providers-ipc@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz#9747c7a6aee96a51488e32fa7c636c3460b39889" - integrity sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA== - dependencies: - oboe "2.1.5" - web3-core-helpers "1.10.0" - -web3-providers-ws@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz#cb0b87b94c4df965cdf486af3a8cd26daf3975e5" - integrity sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ== - dependencies: - eventemitter3 "4.0.4" - web3-core-helpers "1.10.0" - websocket "^1.0.32" - -web3-utils@1.10.0, web3-utils@^1.3.6, web3-utils@^1.8.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578" - integrity sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg== - dependencies: - bn.js "^5.2.1" - 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@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= - -websocket@^1.0.32: - version "1.0.34" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" - 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" - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - 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" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which-typed-array@^1.1.10, which-typed-array@^1.1.11: - version "1.1.11" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which-typed-array@^1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" - 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" - -which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -wordwrapjs@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" - -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@8.13.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== - -ws@^7.4.6: - version "7.5.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" - integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== - -xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yaeti@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" - integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@13.1.2, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" - integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== - dependencies: - flat "^4.1.0" - lodash "^4.17.15" - yargs "^13.3.0" - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@13.3.2, yargs@^13.3.0: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - 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" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - 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" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/proxy/scripts/generateAbi.ts b/scripts/generateAbi.ts similarity index 100% rename from proxy/scripts/generateAbi.ts rename to scripts/generateAbi.ts diff --git a/proxy/ima_datafile_generator.py b/scripts/ima_datafile_generator.py similarity index 100% rename from proxy/ima_datafile_generator.py rename to scripts/ima_datafile_generator.py diff --git a/proxy/scripts/magic_upgrade.sh b/scripts/magic_upgrade.sh similarity index 100% rename from proxy/scripts/magic_upgrade.sh rename to scripts/magic_upgrade.sh diff --git a/proxy/scripts/prepare-docs.sh b/scripts/prepare-docs.sh similarity index 100% rename from proxy/scripts/prepare-docs.sh rename to scripts/prepare-docs.sh diff --git a/proxy/scripts/requirements.txt b/scripts/requirements.txt similarity index 100% rename from proxy/scripts/requirements.txt rename to scripts/requirements.txt diff --git a/proxy/scripts/test_deploy.sh b/scripts/test_deploy.sh similarity index 100% rename from proxy/scripts/test_deploy.sh rename to scripts/test_deploy.sh diff --git a/proxy/scripts/test_predeployed.sh b/scripts/test_predeployed.sh similarity index 100% rename from proxy/scripts/test_predeployed.sh rename to scripts/test_predeployed.sh diff --git a/proxy/scripts/test_upgrade.sh b/scripts/test_upgrade.sh similarity index 100% rename from proxy/scripts/test_upgrade.sh rename to scripts/test_upgrade.sh diff --git a/proxy/scripts/updateManifest.py b/scripts/updateManifest.py similarity index 100% rename from proxy/scripts/updateManifest.py rename to scripts/updateManifest.py diff --git a/proxy/scripts/upgrade-instruction.md b/scripts/upgrade-instruction.md similarity index 100% rename from proxy/scripts/upgrade-instruction.md rename to scripts/upgrade-instruction.md diff --git a/proxy/slither.config.json b/slither.config.json similarity index 100% rename from proxy/slither.config.json rename to slither.config.json diff --git a/proxy/test/CommunityLocker.ts b/test/CommunityLocker.ts similarity index 100% rename from proxy/test/CommunityLocker.ts rename to test/CommunityLocker.ts diff --git a/proxy/test/CommunityPool.ts b/test/CommunityPool.ts similarity index 100% rename from proxy/test/CommunityPool.ts rename to test/CommunityPool.ts diff --git a/proxy/test/DepositBoxERC1155.ts b/test/DepositBoxERC1155.ts similarity index 100% rename from proxy/test/DepositBoxERC1155.ts rename to test/DepositBoxERC1155.ts diff --git a/proxy/test/DepositBoxERC20.ts b/test/DepositBoxERC20.ts similarity index 100% rename from proxy/test/DepositBoxERC20.ts rename to test/DepositBoxERC20.ts diff --git a/proxy/test/DepositBoxERC721.ts b/test/DepositBoxERC721.ts similarity index 100% rename from proxy/test/DepositBoxERC721.ts rename to test/DepositBoxERC721.ts diff --git a/proxy/test/DepositBoxERC721WithMetadata.ts b/test/DepositBoxERC721WithMetadata.ts similarity index 100% rename from proxy/test/DepositBoxERC721WithMetadata.ts rename to test/DepositBoxERC721WithMetadata.ts diff --git a/proxy/test/DepositBoxEth.ts b/test/DepositBoxEth.ts similarity index 100% rename from proxy/test/DepositBoxEth.ts rename to test/DepositBoxEth.ts diff --git a/proxy/test/ERC20OnChain.ts b/test/ERC20OnChain.ts similarity index 100% rename from proxy/test/ERC20OnChain.ts rename to test/ERC20OnChain.ts diff --git a/proxy/test/ERC721OnChain.ts b/test/ERC721OnChain.ts similarity index 100% rename from proxy/test/ERC721OnChain.ts rename to test/ERC721OnChain.ts diff --git a/proxy/test/Linker.ts b/test/Linker.ts similarity index 100% rename from proxy/test/Linker.ts rename to test/Linker.ts diff --git a/proxy/test/MessageProxy.ts b/test/MessageProxy.ts similarity index 100% rename from proxy/test/MessageProxy.ts rename to test/MessageProxy.ts diff --git a/proxy/test/TokenManagerERC1155.ts b/test/TokenManagerERC1155.ts similarity index 100% rename from proxy/test/TokenManagerERC1155.ts rename to test/TokenManagerERC1155.ts diff --git a/proxy/test/TokenManagerERC20.ts b/test/TokenManagerERC20.ts similarity index 100% rename from proxy/test/TokenManagerERC20.ts rename to test/TokenManagerERC20.ts diff --git a/proxy/test/TokenManagerERC721.ts b/test/TokenManagerERC721.ts similarity index 100% rename from proxy/test/TokenManagerERC721.ts rename to test/TokenManagerERC721.ts diff --git a/proxy/test/TokenManagerERC721WithMetadata.ts b/test/TokenManagerERC721WithMetadata.ts similarity index 100% rename from proxy/test/TokenManagerERC721WithMetadata.ts rename to test/TokenManagerERC721WithMetadata.ts diff --git a/proxy/test/TokenManagerEth.ts b/test/TokenManagerEth.ts similarity index 100% rename from proxy/test/TokenManagerEth.ts rename to test/TokenManagerEth.ts diff --git a/proxy/test/TokenManagerLinker.ts b/test/TokenManagerLinker.ts similarity index 100% rename from proxy/test/TokenManagerLinker.ts rename to test/TokenManagerLinker.ts diff --git a/proxy/test/extensions/ERC721MintingFromSchainToMainnet.ts b/test/extensions/ERC721MintingFromSchainToMainnet.ts similarity index 100% rename from proxy/test/extensions/ERC721MintingFromSchainToMainnet.ts rename to test/extensions/ERC721MintingFromSchainToMainnet.ts diff --git a/proxy/test/utils/command_line.ts b/test/utils/command_line.ts similarity index 100% rename from proxy/test/utils/command_line.ts rename to test/utils/command_line.ts diff --git a/proxy/test/utils/deploy/erc1155OnChain.ts b/test/utils/deploy/erc1155OnChain.ts similarity index 100% rename from proxy/test/utils/deploy/erc1155OnChain.ts rename to test/utils/deploy/erc1155OnChain.ts diff --git a/proxy/test/utils/deploy/erc20OnChain.ts b/test/utils/deploy/erc20OnChain.ts similarity index 100% rename from proxy/test/utils/deploy/erc20OnChain.ts rename to test/utils/deploy/erc20OnChain.ts diff --git a/proxy/test/utils/deploy/erc721OnChain.ts b/test/utils/deploy/erc721OnChain.ts similarity index 100% rename from proxy/test/utils/deploy/erc721OnChain.ts rename to test/utils/deploy/erc721OnChain.ts diff --git a/proxy/test/utils/deploy/mainnet/communityPool.ts b/test/utils/deploy/mainnet/communityPool.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/communityPool.ts rename to test/utils/deploy/mainnet/communityPool.ts diff --git a/proxy/test/utils/deploy/mainnet/depositBoxERC1155.ts b/test/utils/deploy/mainnet/depositBoxERC1155.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/depositBoxERC1155.ts rename to test/utils/deploy/mainnet/depositBoxERC1155.ts diff --git a/proxy/test/utils/deploy/mainnet/depositBoxERC20.ts b/test/utils/deploy/mainnet/depositBoxERC20.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/depositBoxERC20.ts rename to test/utils/deploy/mainnet/depositBoxERC20.ts diff --git a/proxy/test/utils/deploy/mainnet/depositBoxERC721.ts b/test/utils/deploy/mainnet/depositBoxERC721.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/depositBoxERC721.ts rename to test/utils/deploy/mainnet/depositBoxERC721.ts diff --git a/proxy/test/utils/deploy/mainnet/depositBoxERC721WithMetadata.ts b/test/utils/deploy/mainnet/depositBoxERC721WithMetadata.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/depositBoxERC721WithMetadata.ts rename to test/utils/deploy/mainnet/depositBoxERC721WithMetadata.ts diff --git a/proxy/test/utils/deploy/mainnet/depositBoxEth.ts b/test/utils/deploy/mainnet/depositBoxEth.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/depositBoxEth.ts rename to test/utils/deploy/mainnet/depositBoxEth.ts diff --git a/proxy/test/utils/deploy/mainnet/linker.ts b/test/utils/deploy/mainnet/linker.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/linker.ts rename to test/utils/deploy/mainnet/linker.ts diff --git a/proxy/test/utils/deploy/mainnet/messageProxyForMainnet.ts b/test/utils/deploy/mainnet/messageProxyForMainnet.ts similarity index 100% rename from proxy/test/utils/deploy/mainnet/messageProxyForMainnet.ts rename to test/utils/deploy/mainnet/messageProxyForMainnet.ts diff --git a/proxy/test/utils/deploy/messages.ts b/test/utils/deploy/messages.ts similarity index 100% rename from proxy/test/utils/deploy/messages.ts rename to test/utils/deploy/messages.ts diff --git a/proxy/test/utils/deploy/schain/communityLocker.ts b/test/utils/deploy/schain/communityLocker.ts similarity index 100% rename from proxy/test/utils/deploy/schain/communityLocker.ts rename to test/utils/deploy/schain/communityLocker.ts diff --git a/proxy/test/utils/deploy/schain/ethErc20.ts b/test/utils/deploy/schain/ethErc20.ts similarity index 100% rename from proxy/test/utils/deploy/schain/ethErc20.ts rename to test/utils/deploy/schain/ethErc20.ts diff --git a/proxy/test/utils/deploy/schain/messageProxyForSchain.ts b/test/utils/deploy/schain/messageProxyForSchain.ts similarity index 100% rename from proxy/test/utils/deploy/schain/messageProxyForSchain.ts rename to test/utils/deploy/schain/messageProxyForSchain.ts diff --git a/proxy/test/utils/deploy/schain/tokenManagerERC1155.ts b/test/utils/deploy/schain/tokenManagerERC1155.ts similarity index 100% rename from proxy/test/utils/deploy/schain/tokenManagerERC1155.ts rename to test/utils/deploy/schain/tokenManagerERC1155.ts diff --git a/proxy/test/utils/deploy/schain/tokenManagerERC20.ts b/test/utils/deploy/schain/tokenManagerERC20.ts similarity index 100% rename from proxy/test/utils/deploy/schain/tokenManagerERC20.ts rename to test/utils/deploy/schain/tokenManagerERC20.ts diff --git a/proxy/test/utils/deploy/schain/tokenManagerERC721.ts b/test/utils/deploy/schain/tokenManagerERC721.ts similarity index 100% rename from proxy/test/utils/deploy/schain/tokenManagerERC721.ts rename to test/utils/deploy/schain/tokenManagerERC721.ts diff --git a/proxy/test/utils/deploy/schain/tokenManagerERC721WithMetadata.ts b/test/utils/deploy/schain/tokenManagerERC721WithMetadata.ts similarity index 100% rename from proxy/test/utils/deploy/schain/tokenManagerERC721WithMetadata.ts rename to test/utils/deploy/schain/tokenManagerERC721WithMetadata.ts diff --git a/proxy/test/utils/deploy/schain/tokenManagerEth.ts b/test/utils/deploy/schain/tokenManagerEth.ts similarity index 100% rename from proxy/test/utils/deploy/schain/tokenManagerEth.ts rename to test/utils/deploy/schain/tokenManagerEth.ts diff --git a/proxy/test/utils/deploy/schain/tokenManagerLinker.ts b/test/utils/deploy/schain/tokenManagerLinker.ts similarity index 100% rename from proxy/test/utils/deploy/schain/tokenManagerLinker.ts rename to test/utils/deploy/schain/tokenManagerLinker.ts diff --git a/proxy/test/utils/deploy/test/communityPoolTester.ts b/test/utils/deploy/test/communityPoolTester.ts similarity index 100% rename from proxy/test/utils/deploy/test/communityPoolTester.ts rename to test/utils/deploy/test/communityPoolTester.ts diff --git a/proxy/test/utils/deploy/test/fallbackEthTester.ts b/test/utils/deploy/test/fallbackEthTester.ts similarity index 100% rename from proxy/test/utils/deploy/test/fallbackEthTester.ts rename to test/utils/deploy/test/fallbackEthTester.ts diff --git a/proxy/test/utils/deploy/test/keyStorageMock.ts b/test/utils/deploy/test/keyStorageMock.ts similarity index 100% rename from proxy/test/utils/deploy/test/keyStorageMock.ts rename to test/utils/deploy/test/keyStorageMock.ts diff --git a/proxy/test/utils/deploy/test/messageProxyCaller.ts b/test/utils/deploy/test/messageProxyCaller.ts similarity index 100% rename from proxy/test/utils/deploy/test/messageProxyCaller.ts rename to test/utils/deploy/test/messageProxyCaller.ts diff --git a/proxy/test/utils/deploy/test/messageProxyForMainnetTester.ts b/test/utils/deploy/test/messageProxyForMainnetTester.ts similarity index 100% rename from proxy/test/utils/deploy/test/messageProxyForMainnetTester.ts rename to test/utils/deploy/test/messageProxyForMainnetTester.ts diff --git a/proxy/test/utils/deploy/test/messageProxyForSchainTester.ts b/test/utils/deploy/test/messageProxyForSchainTester.ts similarity index 100% rename from proxy/test/utils/deploy/test/messageProxyForSchainTester.ts rename to test/utils/deploy/test/messageProxyForSchainTester.ts diff --git a/proxy/test/utils/helper.ts b/test/utils/helper.ts similarity index 100% rename from proxy/test/utils/helper.ts rename to test/utils/helper.ts diff --git a/proxy/test/utils/skale-manager-utils/contractManager.ts b/test/utils/skale-manager-utils/contractManager.ts similarity index 100% rename from proxy/test/utils/skale-manager-utils/contractManager.ts rename to test/utils/skale-manager-utils/contractManager.ts diff --git a/proxy/test/utils/skale-manager-utils/keyStorage.ts b/test/utils/skale-manager-utils/keyStorage.ts similarity index 100% rename from proxy/test/utils/skale-manager-utils/keyStorage.ts rename to test/utils/skale-manager-utils/keyStorage.ts diff --git a/proxy/test/utils/skale-manager-utils/nodes.ts b/test/utils/skale-manager-utils/nodes.ts similarity index 100% rename from proxy/test/utils/skale-manager-utils/nodes.ts rename to test/utils/skale-manager-utils/nodes.ts diff --git a/proxy/test/utils/skale-manager-utils/schainsInternal.ts b/test/utils/skale-manager-utils/schainsInternal.ts similarity index 100% rename from proxy/test/utils/skale-manager-utils/schainsInternal.ts rename to test/utils/skale-manager-utils/schainsInternal.ts diff --git a/proxy/test/utils/skale-manager-utils/wallets.ts b/test/utils/skale-manager-utils/wallets.ts similarity index 100% rename from proxy/test/utils/skale-manager-utils/wallets.ts rename to test/utils/skale-manager-utils/wallets.ts diff --git a/proxy/test/utils/time.ts b/test/utils/time.ts similarity index 100% rename from proxy/test/utils/time.ts rename to test/utils/time.ts diff --git a/proxy/tsconfig.json b/tsconfig.json similarity index 100% rename from proxy/tsconfig.json rename to tsconfig.json diff --git a/yarn.lock b/yarn.lock index 747169a4d..73b7af7b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,43 +2,1876 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@aws-crypto/sha256-js@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz#02acd1a1fda92896fc5a28ec7c6e164644ea32fc" + integrity sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g== + dependencies: + "@aws-crypto/util" "^1.2.2" + "@aws-sdk/types" "^3.1.0" + tslib "^1.11.1" + +"@aws-crypto/util@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-1.2.2.tgz#b28f7897730eb6538b21c18bd4de22d0ea09003c" + integrity sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg== + dependencies: + "@aws-sdk/types" "^3.1.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-sdk/types@^3.1.0": + version "3.378.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.378.0.tgz#93a811ccdf15c81b1947f1cd67922c4690792189" + integrity sha512-qP0CvR/ItgktmN8YXpGQglzzR/6s0nrsQ4zIfx3HMwpsBTwuouYahcCtF1Vr82P4NFcoDA412EJahJ2pIqEd+w== + dependencies: + "@smithy/types" "^2.0.2" + tslib "^2.5.0" + +"@aws-sdk/util-utf8-browser@^3.0.0": + version "3.259.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" + integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== + dependencies: + tslib "^2.3.1" + "@babel/code-frame@^7.0.0": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" - integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" + integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== + dependencies: + "@babel/highlight" "^7.14.5" + +"@babel/helper-validator-identifier@^7.14.5": + version "7.15.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" + integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== + +"@babel/highlight@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@chainsafe/as-sha256@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" + integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== + +"@chainsafe/persistent-merkle-tree@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" + integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/persistent-merkle-tree@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" + integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/ssz@^0.10.0": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" + integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.5.0" + +"@chainsafe/ssz@^0.9.2": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" + integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.4.2" + case "^1.6.3" + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.6.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" + integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== + +"@eslint/eslintrc@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.1.tgz#18d635e24ad35f7276e8a49d135c7d3ca6a46f93" + integrity sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@^8.46.0": + version "8.46.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.46.0.tgz#3f7802972e8b6fe3f88ed1aabc74ec596c456db6" + integrity sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA== + +"@ethereum-waffle/chai@4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-4.0.10.tgz#6f600a40b6fdaed331eba42b8625ff23f3a0e59a" + integrity sha512-X5RepE7Dn8KQLFO7HHAAe+KeGaX/by14hn90wePGBhzL54tq4Y8JscZFu+/LCwCl6TnkAAy5ebiMoqJ37sFtWw== + dependencies: + "@ethereum-waffle/provider" "4.0.5" + debug "^4.3.4" + json-bigint "^1.0.0" + +"@ethereum-waffle/compiler@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-4.0.3.tgz#069e2df24b879b8a7b78857bad6f8bf6ebc8a5b1" + integrity sha512-5x5U52tSvEVJS6dpCeXXKvRKyf8GICDwiTwUvGD3/WD+DpvgvaoHOL82XqpTSUHgV3bBq6ma5/8gKUJUIAnJCw== + dependencies: + "@resolver-engine/imports" "^0.3.3" + "@resolver-engine/imports-fs" "^0.3.3" + "@typechain/ethers-v5" "^10.0.0" + "@types/mkdirp" "^0.5.2" + "@types/node-fetch" "^2.6.1" + mkdirp "^0.5.1" + node-fetch "^2.6.7" + +"@ethereum-waffle/ens@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-4.0.3.tgz#4a46ac926414f3c83b4e8cc2562c8e2aee06377a" + integrity sha512-PVLcdnTbaTfCrfSOrvtlA9Fih73EeDvFS28JQnT5M5P4JMplqmchhcZB1yg/fCtx4cvgHlZXa0+rOCAk2Jk0Jw== + +"@ethereum-waffle/mock-contract@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-4.0.4.tgz#f13fea29922d87a4d2e7c4fc8fe72ea04d2c13de" + integrity sha512-LwEj5SIuEe9/gnrXgtqIkWbk2g15imM/qcJcxpLyAkOj981tQxXmtV4XmQMZsdedEsZ/D/rbUAOtZbgwqgUwQA== + +"@ethereum-waffle/provider@4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-4.0.5.tgz#8a65dbf0263f4162c9209608205dee1c960e716b" + integrity sha512-40uzfyzcrPh+Gbdzv89JJTMBlZwzya1YLDyim8mVbEqYLP5VRYWoGp0JMyaizgV3hMoUFRqJKVmIUw4v7r3hYw== + dependencies: + "@ethereum-waffle/ens" "4.0.3" + "@ganache/ethereum-options" "0.1.4" + debug "^4.3.4" + ganache "7.4.3" + +"@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.0", "@ethereumjs/block@^3.6.2": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.3.tgz#d96cbd7af38b92ebb3424223dbf773f5ccd27f84" + integrity sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg== + dependencies: + "@ethereumjs/common" "^2.6.5" + "@ethereumjs/tx" "^3.5.2" + ethereumjs-util "^7.1.5" + merkle-patricia-tree "^4.2.4" + +"@ethereumjs/blockchain@^5.5.0": + version "5.5.3" + resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz#aa49a6a04789da6b66b5bcbb0d0b98efc369f640" + integrity sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw== + dependencies: + "@ethereumjs/block" "^3.6.2" + "@ethereumjs/common" "^2.6.4" + "@ethereumjs/ethash" "^1.1.0" + debug "^4.3.3" + ethereumjs-util "^7.1.5" + level-mem "^5.0.1" + lru-cache "^5.1.1" + semaphore-async-await "^1.5.1" + +"@ethereumjs/common@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.0.tgz#feb96fb154da41ee2cc2c5df667621a440f36348" + integrity sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.3" + +"@ethereumjs/common@^2.6.0", "@ethereumjs/common@^2.6.4", "@ethereumjs/common@^2.6.5": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" + integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.5" + +"@ethereumjs/ethash@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-1.1.0.tgz#7c5918ffcaa9cb9c1dc7d12f77ef038c11fb83fb" + 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" + +"@ethereumjs/tx@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.4.0.tgz#7eb1947eefa55eb9cf05b3ca116fb7a3dbd0bce7" + integrity sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw== + dependencies: + "@ethereumjs/common" "^2.6.0" + ethereumjs-util "^7.1.3" + +"@ethereumjs/tx@^3.4.0", "@ethereumjs/tx@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c" + integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw== + dependencies: + "@ethereumjs/common" "^2.6.4" + ethereumjs-util "^7.1.5" + +"@ethereumjs/vm@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.6.0.tgz#e0ca62af07de820143674c30b776b86c1983a464" + 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" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/abi@^5.1.2": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.1.tgz#6ac28fafc9ef6f5a7a37e30356a2eb31fa05d39b" + integrity sha512-9mhbjUk76BiSluiiW4BaYyI58KSbDMMQpCLdsAR+RsT2GyATiNYxVv+pGWRrekmsIdY3I+hOqsYQSTkc8L/mcg== + dependencies: + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/hash" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + +"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + +"@ethersproject/abstract-provider@^5.4.0": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz#e404309a29f771bd4d28dbafadcaa184668c2a6e" + integrity sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/networks" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + "@ethersproject/web" "^5.4.0" + +"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" + integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/abstract-signer@^5.4.0": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz#e4e9abcf4dd4f1ba0db7dff9746a5f78f355ea81" + integrity sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA== + dependencies: + "@ethersproject/abstract-provider" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + +"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + +"@ethersproject/address@^5.0.2", "@ethersproject/address@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.4.0.tgz#ba2d00a0f8c4c0854933b963b9a3a9f6eb4a37a3" + integrity sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/rlp" "^5.4.0" + +"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" + integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + +"@ethersproject/base64@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.4.0.tgz#7252bf65295954c9048c7ca5f43e5c86441b2a9a" + integrity sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ== + dependencies: + "@ethersproject/bytes" "^5.4.0" + +"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" + integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + bn.js "^5.2.1" + +"@ethersproject/bignumber@^5.4.0": + version "5.4.2" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.4.2.tgz#44232e015ae4ce82ac034de549eb3583c71283d8" + integrity sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + bn.js "^4.11.9" + +"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/bytes@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.4.0.tgz#56fa32ce3bf67153756dbaefda921d1d4774404e" + integrity sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA== + dependencies: + "@ethersproject/logger" "^5.4.0" + +"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + +"@ethersproject/constants@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.4.0.tgz#ee0bdcb30bf1b532d2353c977bf2ef1ee117958a" + integrity sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + +"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" + integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + +"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/hash@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.4.0.tgz#d18a8e927e828e22860a011f39e429d388344ae0" + integrity sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA== + dependencies: + "@ethersproject/abstract-signer" "^5.4.0" + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + +"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" + integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" + integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + +"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + +"@ethersproject/keccak256@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.4.0.tgz#7143b8eea4976080241d2bd92e3b1f1bf7025318" + integrity sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A== + dependencies: + "@ethersproject/bytes" "^5.4.0" + js-sha3 "0.5.7" + +"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + +"@ethersproject/logger@^5.4.0": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.4.1.tgz#503bd33683538b923c578c07d1c2c0dd18672054" + integrity sha512-DZ+bRinnYLPw1yAC64oRl0QyVZj43QeHIhVKfD/+YwSz4wsv1pfwb5SOFjz+r710YEWzU6LrhuSjpSO+6PeE4A== + +"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/networks@^5.4.0": + version "5.4.2" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.4.2.tgz#2247d977626e97e2c3b8ee73cd2457babde0ce35" + integrity sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw== + dependencies: + "@ethersproject/logger" "^5.4.0" + +"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" + integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + +"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/properties@^5.4.0": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.4.1.tgz#9f051f976ce790142c6261ccb7b826eaae1f2f36" + integrity sha512-cyCGlF8wWlIZyizsj2PpbJ9I7rIlUAfnHYwy/T90pdkSn/NFTa5YWZx2wTJBe9V7dD65dcrrEMisCRUJiq6n3w== + dependencies: + "@ethersproject/logger" "^5.4.0" + +"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": + version "5.7.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + bech32 "1.1.4" + ws "7.4.6" + +"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" + integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.4.0.tgz#de61afda5ff979454e76d3b3310a6c32ad060931" + integrity sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + +"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" + integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/signing-key@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.4.0.tgz#2f05120984e81cf89a3d5f6dec5c68ee0894fbec" + integrity sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + bn.js "^4.11.9" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/solidity@5.7.0", "@ethersproject/solidity@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" + integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/strings@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.4.0.tgz#fb12270132dd84b02906a8d895ae7e7fa3d07d9a" + integrity sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + +"@ethersproject/transactions@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.4.0.tgz#a159d035179334bd92f340ce0f77e83e9e1522e0" + integrity sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ== + dependencies: + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/rlp" "^5.4.0" + "@ethersproject/signing-key" "^5.4.0" + +"@ethersproject/units@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" + integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/wallet@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" + integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/json-wallets" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/web@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.4.0.tgz#49fac173b96992334ed36a175538ba07a7413d1f" + integrity sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og== + dependencies: + "@ethersproject/base64" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + +"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" + integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ganache/ethereum-address@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/ethereum-address/-/ethereum-address-0.1.4.tgz#0e6d66f4a24f64bf687cb3ff7358fb85b9d9005e" + integrity sha512-sTkU0M9z2nZUzDeHRzzGlW724xhMLXo2LeX1hixbnjHWY1Zg1hkqORywVfl+g5uOO8ht8T0v+34IxNxAhmWlbw== + dependencies: + "@ganache/utils" "0.1.4" + +"@ganache/ethereum-options@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/ethereum-options/-/ethereum-options-0.1.4.tgz#6a559abb44225e2b8741a8f78a19a46714a71cd6" + integrity sha512-i4l46taoK2yC41FPkcoDlEVoqHS52wcbHPqJtYETRWqpOaoj9hAg/EJIHLb1t6Nhva2CdTO84bG+qlzlTxjAHw== + dependencies: + "@ganache/ethereum-address" "0.1.4" + "@ganache/ethereum-utils" "0.1.4" + "@ganache/options" "0.1.4" + "@ganache/utils" "0.1.4" + bip39 "3.0.4" + seedrandom "3.0.5" + +"@ganache/ethereum-utils@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/ethereum-utils/-/ethereum-utils-0.1.4.tgz#fae4b5b9e642e751ff1fa0cd7316c92996317257" + integrity sha512-FKXF3zcdDrIoCqovJmHLKZLrJ43234Em2sde/3urUT/10gSgnwlpFmrv2LUMAmSbX3lgZhW/aSs8krGhDevDAg== + dependencies: + "@ethereumjs/common" "2.6.0" + "@ethereumjs/tx" "3.4.0" + "@ethereumjs/vm" "5.6.0" + "@ganache/ethereum-address" "0.1.4" + "@ganache/rlp" "0.1.4" + "@ganache/utils" "0.1.4" + emittery "0.10.0" + ethereumjs-abi "0.6.8" + ethereumjs-util "7.1.3" + +"@ganache/options@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/options/-/options-0.1.4.tgz#325b07e6de85094667aaaaf3d653e32404a04b78" + integrity sha512-zAe/craqNuPz512XQY33MOAG6Si1Xp0hCvfzkBfj2qkuPcbJCq6W/eQ5MB6SbXHrICsHrZOaelyqjuhSEmjXRw== + dependencies: + "@ganache/utils" "0.1.4" + bip39 "3.0.4" + seedrandom "3.0.5" + +"@ganache/rlp@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/rlp/-/rlp-0.1.4.tgz#f4043afda83e1a14a4f80607b103daf166a9b374" + integrity sha512-Do3D1H6JmhikB+6rHviGqkrNywou/liVeFiKIpOBLynIpvZhRCgn3SEDxyy/JovcaozTo/BynHumfs5R085MFQ== + dependencies: + "@ganache/utils" "0.1.4" + rlp "2.2.6" + +"@ganache/utils@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@ganache/utils/-/utils-0.1.4.tgz#25d60d7689e3dda6a8a7ad70e3646f07c2c39a1f" + integrity sha512-oatUueU3XuXbUbUlkyxeLLH3LzFZ4y5aSkNbx6tjSIhVTPeh+AuBKYt4eQ73FFcTB3nj/gZoslgAh5CN7O369w== + dependencies: + emittery "0.10.0" + keccak "3.0.1" + seedrandom "3.0.5" + optionalDependencies: + "@trufflesuite/bigint-buffer" "1.1.9" + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@metamask/eth-sig-util@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" + 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" + +"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" + integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== + +"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" + integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@nomicfoundation/ethereumjs-block@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz#6f89664f55febbd723195b6d0974773d29ee133d" + integrity sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.1" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + "@nomicfoundation/ethereumjs-trie" "6.0.1" + "@nomicfoundation/ethereumjs-tx" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + +"@nomicfoundation/ethereumjs-blockchain@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz#80e0bd3535bfeb9baa29836b6f25123dab06a726" + integrity sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.1" + "@nomicfoundation/ethereumjs-common" "4.0.1" + "@nomicfoundation/ethereumjs-ethash" "3.0.1" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + "@nomicfoundation/ethereumjs-trie" "6.0.1" + "@nomicfoundation/ethereumjs-tx" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + abstract-level "^1.0.3" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + level "^8.0.0" + lru-cache "^5.1.1" + memory-level "^1.0.0" + +"@nomicfoundation/ethereumjs-common@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz#4702d82df35b07b5407583b54a45bf728e46a2f0" + integrity sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g== + dependencies: + "@nomicfoundation/ethereumjs-util" "9.0.1" + crc-32 "^1.2.0" + +"@nomicfoundation/ethereumjs-ethash@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz#65ca494d53e71e8415c9a49ef48bc921c538fc41" + integrity sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.1" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-evm@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz#f35681e203363f69ce2b3d3bf9f44d4e883ca1f1" + integrity sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ== + dependencies: + "@ethersproject/providers" "^5.7.1" + "@nomicfoundation/ethereumjs-common" "4.0.1" + "@nomicfoundation/ethereumjs-tx" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-rlp@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz#0b30c1cf77d125d390408e391c4bb5291ef43c28" + integrity sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ== + +"@nomicfoundation/ethereumjs-statemanager@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz#8824a97938db4471911e2d2f140f79195def5935" + integrity sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.1" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + js-sdsl "^4.1.4" + +"@nomicfoundation/ethereumjs-trie@6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz#662c55f6b50659fd4b22ea9f806a7401cafb7717" + integrity sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + "@types/readable-stream" "^2.3.13" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + +"@nomicfoundation/ethereumjs-tx@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz#7629dc2036b4a33c34e9f0a592b43227ef4f0c7d" + integrity sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w== + dependencies: + "@chainsafe/ssz" "^0.9.2" + "@ethersproject/providers" "^5.7.2" + "@nomicfoundation/ethereumjs-common" "4.0.1" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz#530cda8bae33f8b5020a8f199ed1d0a2ce48ec89" + integrity sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA== + dependencies: + "@chainsafe/ssz" "^0.10.0" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-vm@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz#7d035e0993bcad10716c8b36e61dfb87fa3ca05f" + integrity sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.1" + "@nomicfoundation/ethereumjs-blockchain" "7.0.1" + "@nomicfoundation/ethereumjs-common" "4.0.1" + "@nomicfoundation/ethereumjs-evm" "2.0.1" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + "@nomicfoundation/ethereumjs-statemanager" "2.0.1" + "@nomicfoundation/ethereumjs-trie" "6.0.1" + "@nomicfoundation/ethereumjs-tx" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" + integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== + +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" + integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== + +"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" + integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== + +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" + integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== + +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" + integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== + +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" + integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== + +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" + integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== + +"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" + integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== + +"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" + integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" + integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== + +"@nomicfoundation/solidity-analyzer@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" + integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" + +"@nomiclabs/hardhat-ethers@^2.1.0": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz#b41053e360c31a32c2640c9a45ee981a7e603fe0" + integrity sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg== + +"@nomiclabs/hardhat-etherscan@^3.1.0": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" + integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^8.1.0" + chalk "^2.4.2" + debug "^4.1.1" + fs-extra "^7.0.1" + lodash "^4.17.11" + semver "^6.3.0" + table "^6.8.0" + undici "^5.14.0" + +"@nomiclabs/hardhat-waffle@^2.0.2": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz#d11cb063a5f61a77806053e54009c40ddee49a54" + integrity sha512-+Wz0hwmJGSI17B+BhU/qFRZ1l6/xMW82QGXE/Gi+WTmwgJrQefuBs1lIf7hzQ1hLk6hpkvb/zwcNkpVKRYTQYg== + +"@openzeppelin/contracts-upgradeable@^4.4.2": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.0.tgz#26688982f46969018e3ed3199e72a07c8d114275" + integrity sha512-5GeFgqMiDlqGT8EdORadp1ntGF0qzWZLmEY7Wbp/yVhN7/B3NNzCxujuI77ktlyG81N3CUZP8cZe3ZAQ/cW10w== + +"@openzeppelin/contracts-upgradeable@^4.7.1": + version "4.7.1" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.1.tgz#f63fc384255d6ac139e0a2561aa207fd7c14183c" + integrity sha512-5EFiZld3DYFd8aTL8eeMnhnaWh1/oXLXFNuFMrgF3b1DNPshF3LCyO7VR6lc+gac2URJ0BlVcZoCfkk/3MoEfg== + +"@openzeppelin/defender-base-client@^1.46.0": + version "1.47.1" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-base-client/-/defender-base-client-1.47.1.tgz#2044fd048d73778a42eb0c5ae6f1370d0ab4bac9" + integrity sha512-xnopi1tZIh1zY9KF3mo9S2YgMP0I3T11r6jiO1teAw6M0U5Fx2SCjfCVoKV7CLAQGH1VHmAZ7w2CmcEsFvlQng== + dependencies: + amazon-cognito-identity-js "^6.0.1" + async-retry "^1.3.3" + axios "^1.4.0" + lodash "^4.17.19" + node-fetch "^2.6.0" + +"@openzeppelin/hardhat-upgrades@^1.14.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.28.0.tgz#6361f313a8a879d8a08a5e395acf0933bc190950" + integrity sha512-7sb/Jf+X+uIufOBnmHR0FJVWuxEs2lpxjJnLNN6eCJCP8nD0v+Ot5lTOW2Qb/GFnh+fLvJtEkhkowz4ZQ57+zQ== + dependencies: + "@openzeppelin/defender-base-client" "^1.46.0" + "@openzeppelin/platform-deploy-client" "^0.8.0" + "@openzeppelin/upgrades-core" "^1.27.0" + chalk "^4.1.0" + debug "^4.1.1" + proper-lockfile "^4.1.1" + +"@openzeppelin/platform-deploy-client@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/platform-deploy-client/-/platform-deploy-client-0.8.0.tgz#af6596275a19c283d6145f0128cc1247d18223c1" + integrity sha512-POx3AsnKwKSV/ZLOU/gheksj0Lq7Is1q2F3pKmcFjGZiibf+4kjGxr4eSMrT+2qgKYZQH1ZLQZ+SkbguD8fTvA== + dependencies: + "@ethersproject/abi" "^5.6.3" + "@openzeppelin/defender-base-client" "^1.46.0" + axios "^0.21.2" + lodash "^4.17.19" + node-fetch "^2.6.0" + +"@openzeppelin/upgrades-core@^1.27.0": + version "1.27.3" + resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.27.3.tgz#d5578e3a3ccd18a61fc585945be67951480238b5" + integrity sha512-IqlSMUkno1XKF4L46aUqZ4BqHxj4dF0BRGrFcKeG2Q0vrsKoazhY67JG9bO+wMYG4zxl6jgmG0bd5ef9HLcLmw== + dependencies: + cbor "^8.0.0" + chalk "^4.1.0" + compare-versions "^6.0.0" + debug "^4.1.1" + ethereumjs-util "^7.0.3" + minimist "^1.2.7" + proper-lockfile "^4.1.1" + solidity-ast "^0.4.15" + +"@resolver-engine/core@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" + integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== + dependencies: + debug "^3.1.0" + is-url "^1.2.4" + request "^2.85.0" + +"@resolver-engine/fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" + integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== + dependencies: + "@resolver-engine/core" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports-fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" + integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== + dependencies: + "@resolver-engine/fs" "^0.3.3" + "@resolver-engine/imports" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" + integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== + 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" + +"@safe-global/safe-core-sdk-types@^1.9.0", "@safe-global/safe-core-sdk-types@^1.9.2": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk-types/-/safe-core-sdk-types-1.10.1.tgz#94331b982671d2f2b8cc23114c58baf63d460c81" + integrity sha512-BKvuYTLOlY16Rq6qCXglmnL6KxInDuXMFqZMaCzwDKiEh+uoHu3xCumG5tVtWOkCgBF4XEZXMqwZUiLcon7IsA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/contracts" "^5.7.0" + "@safe-global/safe-deployments" "^1.20.2" + web3-core "^1.8.1" + web3-utils "^1.8.1" + +"@safe-global/safe-core-sdk-utils@^1.7.4": + version "1.7.4" + resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk-utils/-/safe-core-sdk-utils-1.7.4.tgz#810d36cf9629129a28eb1b9c6e690b163834b572" + integrity sha512-ITocwSWlFUA1K9VMP/eJiMfgbP/I9qDxAaFz7ukj5N5NZD3ihVQZkmqML6hjse5UhrfjCnfIEcLkNZhtB2XC2Q== + dependencies: + "@safe-global/safe-core-sdk-types" "^1.9.2" + semver "^7.3.8" + web3-utils "^1.8.1" + +"@safe-global/safe-core-sdk@^3.3.2": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk/-/safe-core-sdk-3.3.4.tgz#d404287f9b910feab3e692243aaf62494ff2d2a9" + integrity sha512-tgcK7VWo66Z8632xaYDzUHQ8InPOaI10ELk1wCrO/C3QjPwxjIozbMGOMzF4RZPCSJX2YAHowAvOgmEukgSkxA== + dependencies: + "@ethersproject/solidity" "^5.7.0" + "@safe-global/safe-core-sdk-types" "^1.9.2" + "@safe-global/safe-core-sdk-utils" "^1.7.4" + "@safe-global/safe-deployments" "^1.25.0" + ethereumjs-util "^7.1.5" + semver "^7.3.8" + web3-utils "^1.8.1" + +"@safe-global/safe-deployments@^1.20.2", "@safe-global/safe-deployments@^1.25.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@safe-global/safe-deployments/-/safe-deployments-1.26.0.tgz#b83615b3b5a66e736e08f8ecf2801ed988e9e007" + integrity sha512-Tw89O4/paT19ieMoiWQbqRApb0Bef/DxweS9rxodXAM5EQModkbyFXGZca+YxXE67sLvWjLr2jJUOxwze8mhGw== + dependencies: + semver "^7.3.7" + +"@safe-global/safe-ethers-lib@^1.9.2": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@safe-global/safe-ethers-lib/-/safe-ethers-lib-1.9.4.tgz#049989a302c6f2010c574cf3a834b0cfb9cf67c5" + integrity sha512-WhzcmNun0s0VxeVQKRqaapV0vEpdm76zZBR2Du+S+58u1r57OjZkOSL2Gru0tdwkt3FIZZtE3OhDu09M70pVkA== + dependencies: + "@safe-global/safe-core-sdk-types" "^1.9.2" + "@safe-global/safe-core-sdk-utils" "^1.7.4" + ethers "5.7.2" + +"@safe-global/safe-service-client@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@safe-global/safe-service-client/-/safe-service-client-2.0.2.tgz#85e00017cb7f63d4cc9c9bf9702bd9cb7b27e62e" + integrity sha512-UFmA53EMRU++2mzo547+tCWaw2BknpbuMDjR786pPgm5dhB4ADattTdV7pYqYBMWn4uGoGgb2kaImEq097bATQ== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@safe-global/safe-core-sdk-types" "^1.9.2" + node-fetch "^2.6.6" + +"@scure/base@~1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + +"@scure/bip32@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" + integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== + dependencies: + "@noble/hashes" "~1.2.0" + "@noble/secp256k1" "~1.7.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" + integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== + dependencies: + "@noble/hashes" "~1.2.0" + "@scure/base" "~1.1.0" + +"@sentry/core@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + 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" + +"@sentry/hub@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== + dependencies: + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/minimal@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + 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" + +"@sentry/node@^5.18.1": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" + 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" + +"@sentry/tracing@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + 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" + +"@sentry/types@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== + +"@sentry/utils@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== + dependencies: + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^7.1.0": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@skalenetwork/etherbase-interfaces@^0.0.1-develop.20": + version "0.0.1-develop.20" + resolved "https://registry.yarnpkg.com/@skalenetwork/etherbase-interfaces/-/etherbase-interfaces-0.0.1-develop.20.tgz#33f61e18d695fd47063aa39dce4df335d26b9528" + integrity sha512-j3xnuQtOtjvjAoUMJgSUFxRa9/Egkg1RyA8r6PjcEb33VksE4LWLBy0PNFUFehLZv48595JROTcViGeXXwg5HQ== + +"@skalenetwork/ima-interfaces@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@skalenetwork/ima-interfaces/-/ima-interfaces-2.0.0.tgz#93cb73a5200f7d9753a44c1be3e15156e7ceaf9c" + integrity sha512-Kqm45GHQl56H4pqdWHIcTUfFrE60LAUKI3j2CecebN0T9rKa0DDokvE42VDa3PfK2z6XIJxh7SkF+i6NsLbpjA== + dependencies: + "@skalenetwork/skale-manager-interfaces" "^0.1.2" + +"@skalenetwork/skale-manager-interfaces@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-2.0.0.tgz#afb63131e5c498cfa69219567f9f52b85f0856c9" + integrity sha512-Pge3p4vpeNaXHjwntX+8b38NEcT81a67I32bbnU+l1uSo4kmyXd0VblHMO84H1Azr9TzF3ZmNCG+GI2yntSx2w== + +"@skalenetwork/skale-manager-interfaces@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-0.1.2.tgz#88e543c8cc298cd0cc9559892d746d2d74786da8" + integrity sha512-gapSQJahwWMlTB/xp/kMzB6k+9+Skx/N0fvEloiW4CUrkGkSa8+fj16YmUXX45p1hOc45W+JydiJPNgZtx32Dg== + +"@skalenetwork/upgrade-tools@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@skalenetwork/upgrade-tools/-/upgrade-tools-2.0.2.tgz#533a2d43d43706fc1898e003523464cee49ec11e" + integrity sha512-by5I3TM7RBi4G8FsicwxQE13rqx+XbPYf75x+CJnTELAFxg5UqMaPArG+YlHT2kBjl6O5OsESkCRtwbPcbIjsg== + dependencies: + "@openzeppelin/contracts-upgradeable" "^4.4.2" + "@safe-global/safe-core-sdk" "^3.3.2" + "@safe-global/safe-core-sdk-types" "^1.9.0" + "@safe-global/safe-ethers-lib" "^1.9.2" + "@safe-global/safe-service-client" "^2.0.0" + axios "^0.27.2" + ethereumjs-util "^7.1.4" + +"@smithy/types@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.0.2.tgz#49d42724c909e845bfd80a2e195740614ce497f3" + integrity sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw== + dependencies: + tslib "^2.5.0" + +"@solidity-parser/parser@^0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.13.2.tgz#b6c71d8ca0b382d90a7bbed241f9bc110af65cbe" + integrity sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@solidity-parser/parser@^0.16.0": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" + integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@trufflesuite/bigint-buffer@1.1.10": + version "1.1.10" + resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz#a1d9ca22d3cad1a138b78baaf15543637a3e1692" + integrity sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw== + dependencies: + node-gyp-build "4.4.0" + +"@trufflesuite/bigint-buffer@1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.9.tgz#e2604d76e1e4747b74376d68f1312f9944d0d75d" + integrity sha512-bdM5cEGCOhDSwminryHJbRmXc1x7dPKg6Pqns3qyTwFlxsqUgxE29lsERS3PlIW1HTjoIGMUqsk1zQQwST1Yxw== + dependencies: + node-gyp-build "4.3.0" + +"@trufflesuite/uws-js-unofficial@20.30.0-unofficial.0": + version "20.30.0-unofficial.0" + resolved "https://registry.yarnpkg.com/@trufflesuite/uws-js-unofficial/-/uws-js-unofficial-20.30.0-unofficial.0.tgz#2fbc2f8ef7e82fbeea6abaf7e8a9d42a02b479d3" + integrity sha512-r5X0aOQcuT6pLwTRLD+mPnAM/nlKtvIK4Z+My++A8tTOR0qTjNRx8UB8jzRj3D+p9PMAp5LnpCUUGmz7/TppwA== + dependencies: + ws "8.13.0" + optionalDependencies: + bufferutil "4.0.7" + utf-8-validate "6.0.3" + +"@typechain/ethers-v5@^10.0.0": + version "10.2.1" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz#50241e6957683281ecfa03fb5a6724d8a3ce2391" + integrity sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@typechain/ethers-v5@^11.1.1": + version "11.1.1" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-11.1.1.tgz#23a358135a302140cf89a186592464dd6bbf1f98" + integrity sha512-D9WyUrCJ4Z5Gg8T00HWLpuqn1CqSDXlCiUOOpLaWoCbnZrE2jSIOUwR9blBZNo6LE5058e3niVu6xk205Et7tg== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@typechain/hardhat@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-7.0.0.tgz#ffa7465328150e793007fee616ae7b76ed20784d" + integrity sha512-XB79i5ewg9Met7gMVGfgVkmypicbnI25T5clJBEooMoW2161p4zvKFpoS2O+lBppQyMrPIZkdvl2M3LMDayVcA== + dependencies: + fs-extra "^9.1.0" + +"@types/abstract-leveldown@*": + version "7.2.1" + resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-7.2.1.tgz#bb16403c17754b0c4d5772d71d03b924a03d4c80" + integrity sha512-YK8irIC+eMrrmtGx0H4ISn9GgzLd9dojZWJaMbjp1YHLl2VqqNFBNrL5Q3KjGf4VE3sf/4hmq6EhQZ7kZp1NoQ== + +"@types/bn.js@*": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== + dependencies: + "@types/node" "*" + +"@types/bn.js@^4.11.3": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" + integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== + dependencies: + "@types/node" "*" + +"@types/chai-almost@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/chai-almost/-/chai-almost-1.0.1.tgz#e8a2de03b53c22e9a2dd2c85ef98bde5f19b685c" + integrity sha512-UwJTbGAP8Jc84JwpSeCEiE50LBvE7MD4pWYsWdwgZG/umPjUlAYCEMK4WnzbEQO/08HH2jDJ+Ikm9CPzHWdGGQ== + dependencies: + "@types/chai" "*" + +"@types/chai-as-promised@^7.1.3": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.4.tgz#caf64e76fb056b8c8ced4b761ed499272b737601" + integrity sha512-1y3L1cHePcIm5vXkh1DSGf/zQq5n5xDKG1fpCvf18+uOkpce0Z1ozNFPkyWsVswK7ntN1sZBw3oU6gmN+pDUcA== + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.2.12": + version "4.2.22" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.22.tgz#47020d7e4cf19194d43b5202f35f75bd2ad35ce7" + integrity sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ== + +"@types/elliptic@^6.4.14": + version "6.4.14" + resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.14.tgz#7bbaad60567a588c1f08b10893453e6b9b4de48e" + integrity sha512-z4OBcDAU0GVwDTuwJzQCiL6188QvZMkvoERgcVjq0/mPM8jCfdwZ3x5zQEVoL9WCAru3aG5wl3Z5Ww5wBWn7ZQ== + dependencies: + "@types/bn.js" "*" + +"@types/glob@^7.1.1": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672" + integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/json-schema@^7.0.12": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/level-errors@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/level-errors/-/level-errors-3.0.0.tgz#15c1f4915a5ef763b51651b15e90f6dc081b96a8" + integrity sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ== + +"@types/levelup@^4.3.0": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@types/levelup/-/levelup-4.3.3.tgz#4dc2b77db079b1cf855562ad52321aa4241b8ef4" + integrity sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA== + dependencies: + "@types/abstract-leveldown" "*" + "@types/level-errors" "*" + "@types/node" "*" + +"@types/lru-cache@5.1.1", "@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/minimist@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" + integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + +"@types/mocha@^9.1.0": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== + +"@types/node-fetch@^2.6.1": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.4.tgz#1bc3a26de814f6bf466b25aeb1473fa1afe6a660" + integrity sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*": + version "20.4.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69" + integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg== + +"@types/node@11.11.6": + version "11.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" + integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== + +"@types/node@^12.12.6": + version "12.20.27" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.27.tgz#4141fcad57c332a120591de883e26fe4bb14aaea" + integrity sha512-qZdePUDSLAZRXXV234bLBEUM0nAQjoxbcSwp1rqSMUe1rZ47mwU6OjciR/JvF1Oo8mc0ys6GE0ks0HGgqAZoGg== + +"@types/pbkdf2@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" + integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== + dependencies: + "@types/node" "*" + +"@types/prettier@^2.1.1": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.0.tgz#900b13362610ccd3570fb6eefb911a6732973d00" + integrity sha512-WHRsy5nMpjXfU9B0LqOqPT06EI2+8Xv5NERy0pLxJLbU98q7uhcGogQzfX+rXpU7S5mgHsLxHrLCufZcV/P8TQ== + +"@types/readable-stream@^2.3.13": + version "2.3.15" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" + integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== + dependencies: + "@types/node" "*" + safe-buffer "~5.1.1" + +"@types/resolve@^0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + +"@types/secp256k1@^4.0.1": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" + integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== + dependencies: + "@types/node" "*" + +"@types/seedrandom@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.1.tgz#1254750a4fec4aff2ebec088ccd0bb02e91fedb4" + integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw== + +"@types/semver@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@types/sinon-chai@^3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48" + integrity sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ== + dependencies: + "@types/chai" "*" + "@types/sinon" "*" + +"@types/sinon@*": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.5.tgz#01e7037ac0c6c5c54c1606463421ad5c6afc43e7" + integrity sha512-BrAUy0yq3n84XOykYGvGbDir9nBIYwQm2NdBNQT0DbtDLqh/5nMUsjz5XfwrefFNLPE9B6g8yLOZREpvw0J40A== + dependencies: + "@sinonjs/fake-timers" "^7.1.0" + +"@typescript-eslint/eslint-plugin@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz#41b79923fee46a745a3a50cba1c33c622aa3c79a" + integrity sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.2.1" + "@typescript-eslint/type-utils" "6.2.1" + "@typescript-eslint/utils" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + natural-compare-lite "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.2.1.tgz#e18a31eea1cca8841a565f1701960c8123ed07f9" + integrity sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg== + dependencies: + "@typescript-eslint/scope-manager" "6.2.1" + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/typescript-estree" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz#b6f43a867b84e5671fe531f2b762e0b68f7cf0c4" + integrity sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q== + dependencies: + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + +"@typescript-eslint/type-utils@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz#8eb8a2cccdf39cd7cf93e02bd2c3782dc90b0525" + integrity sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ== + dependencies: + "@typescript-eslint/typescript-estree" "6.2.1" + "@typescript-eslint/utils" "6.2.1" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.2.1.tgz#7fcdeceb503aab601274bf5e210207050d88c8ab" + integrity sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ== + +"@typescript-eslint/typescript-estree@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz#2af6e90c1e91cb725a5fe1682841a3f74549389e" + integrity sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q== + dependencies: + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/visitor-keys" "6.2.1" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.2.1.tgz#2aa4279ec13053d05615bcbde2398e1e8f08c334" + integrity sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.2.1" + "@typescript-eslint/types" "6.2.1" + "@typescript-eslint/typescript-estree" "6.2.1" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz#442e7c09fe94b715a54ebe30e967987c3c41fbf4" + integrity sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA== + dependencies: + "@typescript-eslint/types" "6.2.1" + eslint-visitor-keys "^3.4.1" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +abortcontroller-polyfill@^1.7.3: + version "1.7.5" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" + integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== + +abstract-level@1.0.3, abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" + integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + +abstract-leveldown@7.2.0, abstract-leveldown@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#08d19d4e26fb5be426f7a57004851b39e1795a2e" + integrity sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ== + dependencies: + buffer "^6.0.3" + catering "^2.0.0" + is-buffer "^2.0.5" + level-concat-iterator "^3.0.0" + level-supports "^2.0.1" + queue-microtask "^1.2.3" + +abstract-leveldown@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" + integrity sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ== dependencies: - "@babel/highlight" "^7.22.5" - -"@babel/helper-validator-identifier@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" - integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== - -"@babel/highlight@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" - integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +abstract-leveldown@~6.2.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" + integrity sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ== dependencies: - "@babel/helper-validator-identifier" "^7.22.5" - chalk "^2.0.0" - js-tokens "^4.0.0" + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -acorn-jsx@^5.2.0: +acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^6.0.7: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +adm-zip@^0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.10.2: +ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.6.1, ajv@^6.9.1: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -48,17 +1881,63 @@ ajv@^6.10.0, ajv@^6.10.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-escapes@^4.2.1: +ajv@^8.0.1: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +amazon-cognito-identity-js@^6.0.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.1.tgz#d9a4c1a92f4b059330df8ea075f65106d2605409" + integrity sha512-PxBdufgS8uZShrcIFAsRjmqNXsh/4fXOWUGQOUhKLHWWK1pcp/y+VeFF48avXIWefM8XwsT3JlN6m9J2eHt4LA== + dependencies: + "@aws-crypto/sha256-js" "1.2.2" + buffer "4.9.2" + fast-base64-decode "^1.0.0" + isomorphic-unfetch "^3.0.0" + js-cookie "^2.2.1" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-colors@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + +ansi-colors@4.1.1, ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-escapes@^4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== ansi-regex@^5.0.1: version "5.0.1" @@ -72,13 +1951,44 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" +antlr4@4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" + integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +anymatch@~3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -86,6 +1996,21 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.1, array-back@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + array-buffer-byte-length@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" @@ -94,47 +2019,21 @@ array-buffer-byte-length@^1.0.0: call-bind "^1.0.2" is-array-buffer "^3.0.1" -array-includes@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" - integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" - is-string "^1.0.7" - -array.prototype.findlastindex@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz#bc229aef98f6bd0533a2bc61ff95209875526c9b" - integrity sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.1.3" - -array.prototype.flat@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" - integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-shim-unscopables "^1.0.0" +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.flatmap@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" - integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== +array.prototype.reduce@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" + integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" es-abstract "^1.20.4" - es-shim-unscopables "^1.0.0" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" arraybuffer.prototype.slice@^1.0.1: version "1.0.1" @@ -148,21 +2047,187 @@ arraybuffer.prototype.slice@^1.0.1: is-array-buffer "^3.0.2" is-shared-array-buffer "^1.0.2" +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +ast-parents@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" + integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async-eventemitter@0.2.4, async-eventemitter@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== + dependencies: + async "^2.4.0" + +async-retry@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== + dependencies: + retry "0.13.1" + +async@1.x: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@^2.4.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + +axios@^0.21.2, axios@^0.21.4: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base-x@^3.0.2: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +bech32@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bigint-crypto-utils@^3.0.23: + version "3.3.0" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" + integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== + +bignumber.js@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" + integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bip39@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" + integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== + dependencies: + "@types/node" "11.11.6" + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + +blakejs@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== + +bn.js@4.11.6: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= + +bn.js@^4.0.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.8, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -171,6 +2236,143 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browser-level@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" + integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.1" + module-error "^1.0.2" + run-parallel-limit "^1.1.0" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + 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" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer-xor@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" + integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== + dependencies: + safe-buffer "^5.1.1" + +buffer@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" + integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A== + dependencies: + node-gyp-build "^4.3.0" + +bufferutil@4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + dependencies: + node-gyp-build "^4.3.0" + +bufferutil@^4.0.1: + version "4.0.4" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.4.tgz#ab81373d313a6ead0d734e98c448c722734ae7bb" + integrity sha512-VNxjXUCrF3LvbLgwfkTb5LsFvk6pGIn7OBb9x+3o+iJ6mKw0JTUp4chBFc88hi1aspeZGeZG9jAIbpFYPQSLZw== + dependencies: + node-gyp-build "^4.2.0" + +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -179,12 +2381,97 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -chalk@^2.0.0, chalk@^2.1.0: +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +case@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" + integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +catering@^2.0.0, catering@^2.1.0, catering@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" + integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== + +cbor@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.0.0.tgz#51657d26a99a6a1866f8c3258e948576eb17d709" + integrity sha512-nMmaLWbj7+bC6MsApKRIig8h+yjgNLhPLXaCelq5+C7mpWsHgIcseZSdvgexSY5uE1Q3m2uPvIDZwSdxdo7qig== + dependencies: + nofilter "^3.0.2" + +cbor@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" + integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== + dependencies: + nofilter "^3.1.0" + +chai-almost@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chai-almost/-/chai-almost-1.0.1.tgz#43d026cf3be79a1cd513cf15af840a81243a4b60" + integrity sha1-Q9AmzzvnmhzVE88Vr4QKgSQ6S2A= + dependencies: + deep-eql "^2.0.2" + type-detect "^4.0.3" + +chai-as-promised@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" + integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== + dependencies: + check-error "^1.0.2" + +chai@^4.2.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" + 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" + +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -193,7 +2480,7 @@ chalk@^2.0.0, chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -206,17 +2493,114 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +chokidar@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" + 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" + optionalDependencies: + fsevents "~2.1.1" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + 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" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@^3.4.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + 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" + optionalDependencies: + fsevents "~2.3.2" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: - restore-cursor "^3.1.0" + inherits "^2.0.1" + safe-buffer "^5.0.1" -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +classic-level@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" + integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.0" + module-error "^1.0.1" + napi-macros "^2.2.2" + node-gyp-build "^4.3.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" color-convert@^1.9.0: version "1.9.3" @@ -235,17 +2619,132 @@ color-convert@^2.0.1: color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +command-exists@^1.2.8: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + +command-line-args@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^6.1.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== + dependencies: + array-back "^4.0.2" + chalk "^2.4.2" + table-layout "^1.0.2" + typical "^5.2.0" + +commander@2.18.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" + integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== + +commander@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + +commander@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +compare-versions@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.0.0.tgz#a3edb527e4487bfab9a8b62ffe70cebc9b87675b" + integrity sha512-s2MzYxfRsE9f/ow8hjn7ysa7pod1xhHdQMsgiJtKx6XSNf4x2N1KG4fjrkUmXcP/e9Y2ZX4zB6sHIso0Lm6evQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +cookie@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +core-js-pure@^3.0.1: + version "3.32.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.32.0.tgz#5d79f85da7a4373e9a06494ccbef995a4c639f8b" + integrity sha512-qsev1H+dTNYpDUEURRuOXMvpdtAnNEvQWS/FMJ2Vb5AY8ZP4rAPQldkE27joykZPJTe0+IVgHZYh1P5Xu1/i1g== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +cosmiconfig@^5.0.7: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + 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" + +crc-32@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" + integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + 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" + +create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + 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" + +cross-fetch@^3.1.4: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" cross-spawn@^6.0.5: version "6.0.5" @@ -258,26 +2757,113 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -debug@^3.2.7: +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +death@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" + integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= + +debug@3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@4, debug@^4.0.1, debug@^4.1.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@4.3.4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^2.2.0, debug@^2.6.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.0: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@^4.0.1: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-eql@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-2.0.2.tgz#b1bac06e56f0a76777686d50c9feb75c2ed7679a" + integrity sha1-sbrAblbwp2d3aG1Qyf63XC7XZ5o= dependencies: - ms "2.1.2" + type-detect "^3.0.0" + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: +deferred-leveldown@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" + integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== + dependencies: + abstract-leveldown "~6.2.1" + inherits "^2.0.3" + +define-properties@^1.1.2, define-properties@^1.1.4, define-properties@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== @@ -285,12 +2871,59 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: - esutils "^2.0.2" + object-keys "^1.0.12" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +detect-port@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +difflib@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" + integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w== + dependencies: + heap ">= 0.2.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" doctrine@^3.0.0: version "3.0.0" @@ -299,6 +2932,37 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dotenv@^16.0.0: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + 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" + +emittery@0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.0.tgz#bb373c660a9d421bb44706ec4967ed50c02a8026" + integrity sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ== + emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -309,6 +2973,66 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +encoding-down@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" + integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== + dependencies: + abstract-leveldown "^6.2.1" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + +enquirer@^2.3.0: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +errno@~0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.18.5: + version "1.18.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.6.tgz#2c44e3ea7a6255039164d26559777a6d978cb456" + integrity sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ== + dependencies: + 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-string "^1.0.7" + 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" + es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: version "1.22.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" @@ -354,6 +3078,11 @@ es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: unbox-primitive "^1.0.2" which-typed-array "^1.1.10" +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + es-set-tostringtag@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" @@ -363,13 +3092,6 @@ es-set-tostringtag@^2.0.1: has "^1.0.3" has-tostringtag "^1.0.0" -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -379,164 +3101,204 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -eslint-config-standard@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" - integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== - -eslint-import-resolver-node@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" - integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== dependencies: - debug "^3.2.7" - is-core-module "^2.11.0" - resolve "^1.22.1" + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" -eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= dependencies: - debug "^3.2.7" + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" -eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@^2.20.2: - version "2.28.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz#8d66d6925117b06c4018d491ae84469eb3cb1005" - integrity sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q== - dependencies: - array-includes "^3.1.6" - array.prototype.findlastindex "^1.2.2" - array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.1" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.7" - eslint-module-utils "^2.8.0" - has "^1.0.3" - is-core-module "^2.12.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.6" - object.groupby "^1.0.0" - object.values "^1.1.6" - resolve "^1.22.3" - semver "^6.3.1" - tsconfig-paths "^3.14.2" - -eslint-plugin-node@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== +es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" + d "^1.0.1" + ext "^1.1.2" -eslint-plugin-promise@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz#61485df2a359e03149fdafc0a68b0e030ad2ac45" - integrity sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -eslint-plugin-standard@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5" - integrity sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ== +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -eslint-scope@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= dependencies: - esrecurse "^4.3.0" + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.3: +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^1.3.1: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== dependencies: eslint-visitor-keys "^1.1.0" -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0: +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz#8c2095440eca8c933bedcadf16fefa44dbe9ba5f" + integrity sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw== + +eslint@^5.6.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== dependencies: "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" + ajv "^6.9.1" chalk "^2.1.0" cross-spawn "^6.0.5" debug "^4.0.1" doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" + 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-parent "^5.0.0" - globals "^12.1.0" + glob "^7.1.2" + globals "^11.7.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" + inquirer "^6.2.2" + js-yaml "^3.13.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.14" + lodash "^4.17.11" minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.3" + optionator "^0.8.2" + path-is-inside "^1.0.2" progress "^2.0.0" regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.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" - v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== +eslint@^8.46.0: + version "8.46.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.46.0.tgz#a06a0ff6974e53e643acc42d1dcf2e7f797b3552" + integrity sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg== dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.1" + "@eslint/js" "^8.46.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.2" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= esprima@^4.0.0: version "4.0.1" @@ -544,34 +3306,249 @@ esprima@^4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esquery@^1.4.2: version "1.5.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" -esrecurse@^4.3.0: +esrecurse@^4.1.0, esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +ethereum-bloom-filters@^1.0.6: + version "1.0.10" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" + integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== + dependencies: + js-sha3 "^0.8.0" + +ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" + 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" + +ethereum-cryptography@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" + integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== + dependencies: + "@noble/hashes" "1.2.0" + "@noble/secp256k1" "1.7.1" + "@scure/bip32" "1.1.5" + "@scure/bip39" "1.1.1" + +ethereum-waffle@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-4.0.10.tgz#f1ef1564c0155236f1a66c6eae362a5d67c9f64c" + integrity sha512-iw9z1otq7qNkGDNcMoeNeLIATF9yKl1M8AIeu42ElfNBplq0e+5PeasQmm8ybY/elkZ1XyRO0JBQxQdVRb8bqQ== + dependencies: + "@ethereum-waffle/chai" "4.0.10" + "@ethereum-waffle/compiler" "4.0.3" + "@ethereum-waffle/mock-contract" "4.0.4" + "@ethereum-waffle/provider" "4.0.5" + solc "0.8.15" + typechain "^8.0.0" + +ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + +ethereumjs-util@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" + 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" + +ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + 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" + +ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.1.tgz#236ef435f46820f0c420a708c0559b5897952069" + integrity sha512-1CGBmCp3m8IMGHhAJF/icH8qjCJrfQtaZ9KW+cAVV8kyN5Lc1IRq3KjV77ILOutrCwiyf5y2gMyCrAUMoCf2Ag== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.4" + +ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.3, ethereumjs-util@^7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" + integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== + 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" + +ethereumjs-util@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" + integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== + 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" + +ethers@5.7.2, ethers@^5.7.1, ethers@^5.7.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== + dependencies: + "@ethersproject/abi" "5.7.0" + "@ethersproject/abstract-provider" "5.7.0" + "@ethersproject/abstract-signer" "5.7.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/base64" "5.7.0" + "@ethersproject/basex" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/bytes" "5.7.0" + "@ethersproject/constants" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/hdnode" "5.7.0" + "@ethersproject/json-wallets" "5.7.0" + "@ethersproject/keccak256" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/networks" "5.7.1" + "@ethersproject/pbkdf2" "5.7.0" + "@ethersproject/properties" "5.7.0" + "@ethersproject/providers" "5.7.2" + "@ethersproject/random" "5.7.0" + "@ethersproject/rlp" "5.7.0" + "@ethersproject/sha2" "5.7.0" + "@ethersproject/signing-key" "5.7.0" + "@ethersproject/solidity" "5.7.0" + "@ethersproject/strings" "5.7.0" + "@ethersproject/transactions" "5.7.0" + "@ethersproject/units" "5.7.0" + "@ethersproject/wallet" "5.7.0" + "@ethersproject/web" "5.7.1" + "@ethersproject/wordlists" "5.7.0" + +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +ethjs-util@0.1.6, ethjs-util@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== + +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -581,25 +3558,74 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -fast-deep-equal@^3.1.1: +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-base64-decode@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418" + integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.0.3: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== + 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" + +fast-glob@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + 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" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" @@ -610,6 +3636,49 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@5.0.0, find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -619,11 +3688,46 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flat@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" + integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== + dependencies: + is-buffer "~2.0.3" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +follow-redirects@^1.12.1, follow-redirects@^1.14.0: + version "1.14.4" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379" + integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g== + +follow-redirects@^1.14.9, follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -631,10 +3735,106 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + +fp-ts@^1.0.0: + version "1.19.5" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" + integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== + +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + 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" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" @@ -651,17 +3851,74 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functional-red-black-tree@^1.0.1: +functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: +ganache@7.4.3: + version "7.4.3" + resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.4.3.tgz#e995f1250697264efbb34d4241c374a2b0271415" + integrity sha512-RpEDUiCkqbouyE7+NMXG26ynZ+7sGiODU84Kz+FVoXUnQ4qQM4M8wif3Y4qUCt+D/eM1RVeGq0my62FPD6Y1KA== + dependencies: + "@trufflesuite/bigint-buffer" "1.1.10" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "5.1.1" + "@types/seedrandom" "3.0.1" + emittery "0.10.0" + keccak "3.0.2" + leveldown "6.1.0" + secp256k1 "4.0.3" + optionalDependencies: + bufferutil "4.0.5" + utf-8-validate "5.0.7" + +ganache@7.9.2: + version "7.9.2" + resolved "https://registry.yarnpkg.com/ganache/-/ganache-7.9.2.tgz#77f506ad2735dd9109696ffa1834a9dd2f806449" + integrity sha512-7gsVVDpO9AhrFyDMWWl7SpMsPpqGcnAzjxz3k32LheIPNd64p2XsY9GYRdhWmKuryb60W1iaWPZWDkFKlbRWHA== + dependencies: + "@trufflesuite/bigint-buffer" "1.1.10" + "@trufflesuite/uws-js-unofficial" "20.30.0-unofficial.0" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "5.1.1" + "@types/seedrandom" "3.0.1" + abstract-level "1.0.3" + abstract-leveldown "7.2.0" + async-eventemitter "0.2.4" + emittery "0.10.0" + keccak "3.0.2" + leveldown "6.1.0" + secp256k1 "4.0.3" + optionalDependencies: + bufferutil "4.0.5" + utf-8-validate "5.0.7" + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== @@ -679,31 +3936,109 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -glob-parent@^5.0.0: +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +ghost-testrpc@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" + integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== + dependencies: + chalk "^2.4.2" + node-emoji "^1.10.0" + +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + 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" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + 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" + +glob@7.2.0, glob@^7.0.0, glob@^7.1.2, glob@^7.1.3: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.1.1" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" once "^1.3.0" path-is-absolute "^1.0.0" -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== dependencies: - type-fest "^0.8.1" + type-fest "^0.20.2" globalthis@^1.0.3: version "1.0.3" @@ -712,6 +4047,32 @@ globalthis@^1.0.3: dependencies: define-properties "^1.1.3" +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + 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" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -719,15 +4080,120 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -has-bigints@^1.0.1, has-bigints@^1.0.2: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +handlebars@^4.0.1: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + 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" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +"hardhat@2.11.0 - 2.16.1": + version "2.16.1" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.16.1.tgz#fd2288ce44f6846a70ba332b3d8158522447262a" + integrity sha512-QpBjGXFhhSYoYBGEHyoau/A63crZOP+i3GbNxzLGkL6IklzT+piN14+wGnINNCg5BLSKisQI/RAySPzaWRcx/g== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/ethereumjs-block" "5.0.1" + "@nomicfoundation/ethereumjs-blockchain" "7.0.1" + "@nomicfoundation/ethereumjs-common" "4.0.1" + "@nomicfoundation/ethereumjs-evm" "2.0.1" + "@nomicfoundation/ethereumjs-rlp" "5.0.1" + "@nomicfoundation/ethereumjs-statemanager" "2.0.1" + "@nomicfoundation/ethereumjs-trie" "6.0.1" + "@nomicfoundation/ethereumjs-tx" "5.0.1" + "@nomicfoundation/ethereumjs-util" "9.0.1" + "@nomicfoundation/ethereumjs-vm" "7.0.1" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.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 "^1.0.3" + ethereumjs-abi "^0.6.8" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "7.2.0" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + keccak "^3.0.2" + lodash "^4.17.11" + mnemonist "^0.38.0" + mocha "^10.0.0" + p-map "^4.0.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + tsort "0.0.1" + undici "^5.14.0" + uuid "^8.3.2" + ws "^7.4.6" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-flag@^4.0.0: version "4.0.0" @@ -746,11 +4212,16 @@ has-proto@^1.0.1: resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== -has-symbols@^1.0.2, has-symbols@^1.0.3: +has-symbols@^1.0.0, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -765,24 +4236,131 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -iconv-lite@^0.4.24: +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +"heap@>= 0.2.0": + version "0.2.7" + resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" + integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hosted-git-info@^2.6.0: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +http-errors@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.1: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== -import-fresh@^3.0.0: +immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +immediate@~3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" + integrity sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg== + +immutable@^4.0.0-rc.12: + version "4.0.0-rc.15" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0-rc.15.tgz#c30056f05eaaf5650fd15230586688fdd15c54bc" + integrity sha512-v8+A3sNyaieoP9dHegl3tEYnIZa7vqNiSv0U6D7YddiZi34VjKy4GsIxrRHj2d8+CS3MeiVja5QyNe4JO/aEXA== + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -793,40 +4371,59 @@ import-fresh@^3.0.0: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inquirer@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inquirer@^6.2.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" + 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 "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" + 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" +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" @@ -836,6 +4433,26 @@ internal-slot@^1.0.5: has "^1.0.3" side-channel "^1.0.4" +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +io-ts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== + dependencies: + fp-ts "^1.0.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" @@ -845,6 +4462,11 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: get-intrinsic "^1.2.0" is-typed-array "^1.1.10" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -852,6 +4474,13 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-boolean-object@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" @@ -860,15 +4489,25 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: +is-buffer@^2.0.5, is-buffer@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.11.0, is-core-module@^2.12.0, is-core-module@^2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" - integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== +is-core-module@^2.2.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19" + integrity sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ== dependencies: has "^1.0.3" @@ -879,40 +4518,84 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.2.tgz#859fc2e731e58c902f99fcabccb75a7dd07d29d8" + integrity sha512-ZZTOjRcDjuAAAv2cTBQP/lL59ZTArx77+7UzHdWW/XB1mrfp7DEaVpKmZ0XIzx+M7AxfhKcqV+nMetUQmFifwg== + dependencies: + is-extglob "^2.1.1" + +is-hex-prefixed@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== dependencies: has-tostringtag "^1.0.0" +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -949,6 +4632,32 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.9: dependencies: which-typed-array "^1.1.11" +is-typed-array@^1.1.3, is-typed-array@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" + 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" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-url@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -956,118 +4665,824 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isomorphic-unfetch@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" + integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== + dependencies: + node-fetch "^2.6.1" + unfetch "^4.2.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + +js-sdsl@^4.1.4: + version "4.4.2" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" + integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== + +js-sha3@0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= + +js-sha3@0.8.0, js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonschema@^1.2.4: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2" + integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +keccak@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" + integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +keccak@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" + integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +keccak@^3.0.0, keccak@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" + integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= + optionalDependencies: + graceful-fs "^4.1.9" + +level-codec@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" + integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== + dependencies: + buffer "^5.6.0" + +level-concat-iterator@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz#5235b1f744bc34847ed65a50548aa88d22e881cf" + integrity sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ== + dependencies: + catering "^2.1.0" + +level-concat-iterator@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" + integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== + +level-errors@^2.0.0, level-errors@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" + integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== + dependencies: + errno "~0.1.1" + +level-iterator-stream@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" + integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== + dependencies: + inherits "^2.0.4" + readable-stream "^3.4.0" + xtend "^4.0.2" + +level-mem@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-5.0.1.tgz#c345126b74f5b8aa376dc77d36813a177ef8251d" + integrity sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg== + dependencies: + level-packager "^5.0.3" + memdown "^5.0.0" + +level-packager@^5.0.3: + version "5.1.1" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" + integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== + dependencies: + encoding-down "^6.3.0" + levelup "^4.3.2" + +level-supports@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-2.1.0.tgz#9af908d853597ecd592293b2fad124375be79c5f" + integrity sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA== + +level-supports@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== + +level-supports@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" + integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== + dependencies: + xtend "^4.0.2" + +level-transcoder@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" + integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== + dependencies: + buffer "^6.0.3" + module-error "^1.0.1" + +level-ws@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" + integrity sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA== + dependencies: + inherits "^2.0.3" + readable-stream "^3.1.0" + xtend "^4.0.1" + +level@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" + integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== + dependencies: + browser-level "^1.0.1" + classic-level "^1.2.0" + +leveldown@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-6.1.0.tgz#7ab1297706f70c657d1a72b31b40323aa612b9ee" + integrity sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w== + dependencies: + abstract-leveldown "^7.2.0" + napi-macros "~2.0.0" + node-gyp-build "^4.3.0" + +levelup@^4.3.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" + 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" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== + +lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= + +ltgt@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA== + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +mcl-wasm@^0.7.1: + version "0.7.9" + resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" + integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +memdown@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb" + 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" + +memory-level@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" + integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== + dependencies: + abstract-level "^1.0.0" + functional-red-black-tree "^1.0.1" + module-error "^1.0.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +merkle-patricia-tree@^4.2.2, merkle-patricia-tree@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz#ff988d045e2bf3dfa2239f7fabe2d59618d57413" + integrity sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w== + dependencies: + "@types/levelup" "^4.3.0" + ethereumjs-util "^7.1.4" + level-mem "^5.0.1" + level-ws "^2.0.0" + readable-stream "^3.6.0" + semaphore-async-await "^1.5.1" + +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: - argparse "^1.0.7" - esprima "^4.0.0" + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.49.0: + version "1.49.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" + integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.32" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" + integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== + dependencies: + mime-db "1.49.0" -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +mime-types@~2.1.19: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" -json-stable-stringify-without-jsonify@^1.0.1: +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lodash@^4.17.14, lodash@^4.17.19: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + brace-expansion "^1.1.7" -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.5, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minimist@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -mkdirp@^0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== +mkdirp@0.5.5, mkdirp@0.5.x, mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mnemonist@^0.38.0: + version "0.38.4" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.4.tgz#5d2f2dc4386aef78bfadeea60ce704dcf0ef8f3d" + integrity sha512-mflgW0gEWmVLbDDE2gJbOh3+RltTN7CgV9jV25qyCnyLN9FtoltWr7ZtAEDeD9u8W4oFAoolR6fBWieXdn3u8Q== + dependencies: + obliterator "^1.6.1" + +mocha@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.2.tgz#8e40d198acf91a52ace122cd7599c9ab857b29e6" + integrity sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA== dependencies: - minimist "^1.2.6" + 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" + +mocha@^10.0.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +module-error@^1.0.1, module-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" + integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +napi-macros@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== + +napi-macros@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" + integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +neo-async@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -object-inspect@^1.12.3, object-inspect@^1.9.0: +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-emoji@^1.10.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== + dependencies: + lodash "^4.17.21" + +node-environment-flags@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" + integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + +node-fetch@^2.6.0, node-fetch@^2.6.1: + version "2.6.5" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" + integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@^2.6.12, node-fetch@^2.6.6, node-fetch@^2.6.7: + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== + dependencies: + whatwg-url "^5.0.0" + +node-gyp-build@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + +node-gyp-build@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" + integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== + +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" + integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + +nofilter@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.0.3.tgz#3ff3b142efdccb403434ccae4a0c2c835cb9b522" + integrity sha512-TN/MCrQmXQk5DyUJ8TGUq1Il8rv4fTsjddLmMopV006QP8DMkglmGgYfQKD5620vXLRXfr8iGI6ZZ4/ZWld2cQ== + +nofilter@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" + integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== + +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +number-to-bn@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= + dependencies: + bn.js "4.11.6" + strip-hex-prefix "1.0.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + +object-inspect@^1.12.3: version "1.12.3" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== -object-keys@^1.1.1: +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== +object.assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + 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" + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + 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" + object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" @@ -1078,49 +5493,44 @@ object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.fromentries@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" - integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -object.groupby@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.0.tgz#cb29259cf90f37e7bac6437686c1ea8c916d12a9" - integrity sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw== +object.getownpropertydescriptors@^2.0.3: + version "2.1.6" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz#5e5c384dd209fa4efffead39e3a0512770ccc312" + integrity sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ== dependencies: + array.prototype.reduce "^1.0.5" call-bind "^1.0.2" define-properties "^1.2.0" es-abstract "^1.21.2" - get-intrinsic "^1.2.1" + safe-array-concat "^1.0.0" + +obliterator@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-1.6.1.tgz#dea03e8ab821f6c4d96a299e17aef6a3af994ef3" + integrity sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig== -object.values@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" - integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== +oboe@2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" + integrity sha1-VVQoTFQ6ImbXo48X4HOCH73jk80= dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + http-https "^1.0.0" -once@^1.3.0: +once@1.x, once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: - mimic-fn "^2.1.0" + mimic-fn "^1.0.0" -optionator@^0.8.3: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -1132,10 +5542,81 @@ optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== parent-module@^1.0.0: version "1.0.1" @@ -1144,36 +5625,240 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +path-browserify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.7: +path-parse@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + +pbkdf2@^3.0.17, pbkdf2@^3.0.9: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + 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" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier@^1.14.3: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +prettier@^2.1.2: + version "2.4.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" + integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== + +prettier@^2.3.1: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +printj@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +proper-lockfile@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" + integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== + dependencies: + graceful-fs "^4.2.4" + retry "^0.12.0" + signal-exit "^3.0.2" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +punycode@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +qs@^6.11.0: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +queue-microtask@^1.2.2, queue-microtask@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.0.1, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +raw-body@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" + integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== + dependencies: + picomatch "^2.0.4" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +recursive-readdir@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +reduce-flatten@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== + regexp.prototype.flags@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" @@ -1188,55 +5873,168 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpp@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +request@^2.85.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + 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" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.0, require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.1, resolve@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: - is-core-module "^2.11.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" + path-parse "^1.0.6" -resolve@^1.22.3: - version "1.22.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.3.tgz#4b4055349ffb962600972da1fdc33c46a4eb3283" - integrity sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw== +resolve@^1.1.6, resolve@^1.8.1: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: - is-core-module "^2.12.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" + is-core-module "^2.2.0" + path-parse "^1.0.6" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: - onetime "^5.1.0" + onetime "^2.0.0" signal-exit "^3.0.2" +retry@0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: - glob "^7.1.3" + glob "^7.1.3" + +rimraf@^2.2.8: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rlp@2.2.6, rlp@^2.2.3: + version "2.2.6" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" + integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg== + dependencies: + bn.js "^4.11.1" + +rlp@^2.2.4: + version "2.2.7" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" + integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== + dependencies: + bn.js "^5.2.0" + +run-async@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" + integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== + dependencies: + queue-microtask "^1.2.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +rustbn.js@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" + integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -rxjs@^6.6.0: +rxjs@^6.4.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== @@ -1253,6 +6051,16 @@ safe-array-concat@^1.0.0: has-symbols "^1.0.3" isarray "^2.0.5" +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -1262,32 +6070,146 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -semver@^5.5.0: +sc-istanbul@^0.4.5: + version "0.4.6" + resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" + 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" + +scrypt-js@3.0.1, scrypt-js@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +secp256k1@4.0.3, secp256k1@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +seedrandom@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" + integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== + +semaphore-async-await@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa" + integrity sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg== + +semver@^5.5.0, semver@^5.5.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^5.7.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.1.0, semver@^6.1.2, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.4: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shelljs@^0.8.3: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" side-channel@^1.0.4: version "1.0.4" @@ -1299,9 +6221,14 @@ side-channel@^1.0.4: object-inspect "^1.9.0" signal-exit@^3.0.2: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.4.tgz#366a4684d175b9cab2081e3681fda3747b6c51d7" + integrity sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@^2.1.0: version "2.1.0" @@ -1312,12 +6239,167 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +solc@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" + 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" + +solc@0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.15.tgz#d274dca4d5a8b7d3c9295d4cbdc9291ee1c52152" + integrity sha512-Riv0GNHNk/SddN/JyEuFKwbcWcEeho15iyupTSHw5Np6WuXA5D8kEHbyzDHi6sqmvLzu2l+8b1YmL8Ytple+8w== + dependencies: + command-exists "^1.2.8" + commander "^8.1.0" + follow-redirects "^1.12.1" + js-sha3 "0.8.0" + memorystream "^0.3.1" + semver "^5.5.0" + tmp "0.0.33" + +solhint@3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.6.tgz#abe9af185a9a7defefba480047b3e42cbe9a1210" + 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" + optionalDependencies: + prettier "^1.14.3" + +solidity-ast@^0.4.15: + version "0.4.49" + resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.49.tgz#ecba89d10c0067845b7848c3a3e8cc61a4fc5b82" + integrity sha512-Pr5sCAj1SFqzwFZw1HPKSq0PehlQNdM8GwKyAVYh2DOn7/cCK8LUKD1HeHnKtTgBW7hi9h4nnnan7hpAg5RhWQ== + +solidity-coverage@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.4.tgz#c57a21979f5e86859c5198de9fbae2d3bc6324a5" + integrity sha512-xeHOfBOjdMF6hWTbt42iH4x+7j1Atmrf5OldDPMxI+i/COdExUxszOswD9qqvcBTaLGiOrrpnh9UZjSpt4rBsg== + dependencies: + "@ethersproject/abi" "^5.0.9" + "@solidity-parser/parser" "^0.16.0" + chalk "^2.4.2" + death "^1.1.0" + detect-port "^1.3.0" + difflib "^0.2.4" + 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" + mocha "7.1.2" + 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.6" + +source-map-support@^0.5.13, source-map-support@^0.5.17: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + 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" + +stacktrace-parser@^0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + +"statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -string-width@^3.0.0: +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + +"string-width@^1.0.2 || 2", string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -1326,7 +6408,7 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -1344,6 +6426,14 @@ string.prototype.trim@^1.2.7: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + string.prototype.trimend@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" @@ -1353,6 +6443,14 @@ string.prototype.trimend@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + string.prototype.trimstart@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" @@ -1362,7 +6460,21 @@ string.prototype.trimstart@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" -strip-ansi@^5.1.0, strip-ansi@^5.2.0: +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== @@ -1376,16 +6488,44 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== +strip-hex-prefix@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= + dependencies: + is-hex-prefixed "1.0.0" + +strip-json-comments@2.0.1, strip-json-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -strip-json-comments@^3.0.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== + dependencies: + has-flag "^3.0.0" + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -1400,10 +6540,15 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +table-layout@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== + dependencies: + array-back "^4.0.1" + deep-extend "~0.6.0" + typical "^5.2.0" + wordwrapjs "^4.0.0" table@^5.2.3: version "5.4.6" @@ -1415,54 +6560,211 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" +table@^6.8.0: + version "6.8.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" + integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -tmp@^0.0.33: +tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" -tsconfig-paths@^3.14.2: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== + +ts-command-line-args@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.2.1.tgz#fd6913e542099012c0ffb2496126a8f38305c7d6" + integrity sha512-mnK68QA86FYzQYTSA/rxIjT/8EpKsvQw9QkawPic8I8t0gjAOw3Oa509NIRoaY1FmH7hdrncMp7t7o+vYoceNQ== + dependencies: + chalk "^4.1.0" + command-line-args "^5.1.1" + command-line-usage "^6.1.0" + string-format "^2.0.0" + +ts-essentials@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" + integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== + +ts-essentials@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" + integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== + +ts-generator@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" + integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== + 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" + +ts-node@^8.10.2: + version "8.10.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" + integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" + arg "^4.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" -tslib@^1.9.0: +tslib@^1.11.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.3.1, tslib@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" + integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== + +tsort@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" + integrity sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl-util@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= dependencies: prelude-ls "~1.1.2" +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.3, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-detect@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-3.0.0.tgz#46d0cc8553abb7b13a352b0d6dea2fd58f2d9b55" + integrity sha1-RtDMhVOrt7E6NSsNbeov1Y8tm1U= + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + +typechain@^8.0.0, typechain@^8.3.1: + version "8.3.1" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.1.tgz#dccbc839b94877997536c356380eff7325395cfb" + integrity sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.3.1" + fs-extra "^7.0.0" + glob "7.1.7" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.3.1" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" typed-array-buffer@^1.0.0: version "1.0.0" @@ -1503,6 +6805,43 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typescript@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== + +uglify-js@^3.1.4: + version "3.14.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.2.tgz#d7dd6a46ca57214f54a2d0a43cad0f35db82ac99" + integrity sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + 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" + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -1513,6 +6852,33 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undici@^5.14.0: + version "5.22.1" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.22.1.tgz#877d512effef2ac8be65e695f3586922e1a57d7b" + integrity sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw== + dependencies: + busboy "^1.6.0" + +unfetch@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -1520,10 +6886,205 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +url@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.1.tgz#26f90f615427eca1b9f4d6a28288c147e2302a32" + integrity sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA== + dependencies: + punycode "^1.4.1" + qs "^6.11.0" + +utf-8-validate@5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.7.tgz#c15a19a6af1f7ad9ec7ddc425747ca28c3644922" + integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q== + dependencies: + node-gyp-build "^4.3.0" + +utf-8-validate@6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-6.0.3.tgz#7d8c936d854e86b24d1d655f138ee27d2636d777" + integrity sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA== + dependencies: + node-gyp-build "^4.3.0" + +utf-8-validate@^5.0.2: + version "5.0.6" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.6.tgz#e1b3e0a5cc8648a3b44c1799fbb170d1aaaffe80" + integrity sha512-hoY0gOf9EkCw+nimK21FVKHUIG1BMqSiRwxB/q3A9yKZOrOI99PP77BxmarDqWz6rG3vVYiBWfhG8z2Tl+7fZA== + dependencies: + node-gyp-build "^4.2.0" + +utf8@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +web3-core-helpers@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.0.tgz#1016534c51a5df77ed4f94d1fcce31de4af37fad" + integrity sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g== + dependencies: + web3-eth-iban "1.10.0" + web3-utils "1.10.0" + +web3-core-method@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.0.tgz#82668197fa086e8cc8066742e35a9d72535e3412" + integrity sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-core-subscriptions "1.10.0" + web3-utils "1.10.0" + +web3-core-promievent@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.0.tgz#cbb5b3a76b888df45ed3a8d4d8d4f54ccb66a37b" + integrity sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg== + dependencies: + eventemitter3 "4.0.4" + +web3-core-requestmanager@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.0.tgz#4b34f6e05837e67c70ff6f6993652afc0d54c340" + integrity sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ== + dependencies: + util "^0.12.5" + web3-core-helpers "1.10.0" + web3-providers-http "1.10.0" + web3-providers-ipc "1.10.0" + web3-providers-ws "1.10.0" + +web3-core-subscriptions@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.0.tgz#b534592ee1611788fc0cb0b95963b9b9b6eacb7c" + integrity sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + +web3-core@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.0.tgz#9aa07c5deb478cf356c5d3b5b35afafa5fa8e633" + integrity sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ== + dependencies: + "@types/bn.js" "^5.1.1" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-requestmanager "1.10.0" + web3-utils "1.10.0" + +web3-eth-iban@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz#5a46646401965b0f09a4f58e7248c8a8cd22538a" + integrity sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg== + dependencies: + bn.js "^5.2.1" + web3-utils "1.10.0" + +web3-providers-http@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.0.tgz#864fa48675e7918c9a4374e5f664b32c09d0151b" + integrity sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA== + dependencies: + abortcontroller-polyfill "^1.7.3" + cross-fetch "^3.1.4" + es6-promise "^4.2.8" + web3-core-helpers "1.10.0" + +web3-providers-ipc@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz#9747c7a6aee96a51488e32fa7c636c3460b39889" + integrity sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.10.0" + +web3-providers-ws@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz#cb0b87b94c4df965cdf486af3a8cd26daf3975e5" + integrity sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + websocket "^1.0.32" + +web3-utils@1.10.0, web3-utils@^1.3.6, web3-utils@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578" + integrity sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg== + dependencies: + bn.js "^5.2.1" + 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@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + +websocket@^1.0.32: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + 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" + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" which-boxed-primitive@^1.0.2: version "1.0.2" @@ -1536,6 +7097,11 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + which-typed-array@^1.1.10, which-typed-array@^1.1.11: version "1.1.11" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" @@ -1547,22 +7113,84 @@ which-typed-array@^1.1.10, which-typed-array@^1.1.11: gopd "^1.0.1" has-tostringtag "^1.0.0" -which@^1.2.9: +which-typed-array@^1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" + 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" + +which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + word-wrap@~1.2.3: - version "1.2.5" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" - integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wordwrapjs@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== + dependencies: + reduce-flatten "^2.0.0" + typical "^5.2.0" + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write@1.0.3: version "1.0.3" @@ -1570,3 +7198,124 @@ write@1.0.3: integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== dependencies: mkdirp "^0.5.1" + +ws@7.4.6: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +ws@8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + +ws@^7.4.6: + version "7.5.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" + integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== + +xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@13.1.2, yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" + integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== + dependencies: + flat "^4.1.0" + lodash "^4.17.15" + yargs "^13.3.0" + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@13.3.2, yargs@^13.3.0: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + 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" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + 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" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==